Changes in / [e06be49:a9a4771]


Ignore:
Location:
src
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    re06be49 ra9a4771  
    8989                } else if ( currentLocation.followedBy( to, 1 ) ) {
    9090                        output << "\n" << indent;
    91                         currentLocation.linenumber += 1;
     91                        currentLocation.first_line += 1;
    9292                } else if ( currentLocation.followedBy( to, 2 ) ) {
    9393                        output << "\n\n" << indent;
    94                         currentLocation.linenumber += 2;
    95                 } else {
    96                         output << "\n# " << to.linenumber << " \"" << to.filename
     94                        currentLocation.first_line += 2;
     95                } else {
     96                        output << "\n# " << to.first_line << " \"" << to.filename
    9797                               << "\"\n" << indent;
    9898                        currentLocation = to;
     
    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 {
    462475                                                // no constructors with 0 or more than 2 parameters
    463                                                 assert( false );
     476                                                assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     477                                                output << "(";
     478                                                (*arg++)->accept( *visitor );
     479                                                output << opInfo.symbol << "{ ";
     480                                                genCommaList( arg, untypedExpr->get_args().end() );
     481                                                output << "}) /* " << opInfo.inputName << " */";
    464482                                        } // if
    465483                                        break;
     
    471489                                        output << "(";
    472490                                        output << opInfo.symbol;
    473                                         (*arg)->accept( *this );
     491                                        (*arg)->accept( *visitor );
    474492                                        output << ")";
    475493                                        break;
     
    478496                                  case OT_POSTFIXASSIGN:
    479497                                        assert( untypedExpr->get_args().size() == 1 );
    480                                         (*arg)->accept( *this );
     498                                        (*arg)->accept( *visitor );
    481499                                        output << opInfo.symbol;
    482500                                        break;
     
    486504                                        assert( untypedExpr->get_args().size() == 2 );
    487505                                        output << "(";
    488                                         (*arg++)->accept( *this );
     506                                        (*arg++)->accept( *visitor );
    489507                                        output << opInfo.symbol;
    490                                         (*arg)->accept( *this );
     508                                        (*arg)->accept( *visitor );
    491509                                        output << ")";
    492510                                        break;
     
    499517                                if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    500518                                        assert( untypedExpr->get_args().size() == 2 );
    501                                         (*untypedExpr->get_args().begin())->accept( *this );
     519                                        (*untypedExpr->get_args().begin())->accept( *visitor );
    502520                                        output << " ... ";
    503                                         (*--untypedExpr->get_args().end())->accept( *this );
     521                                        (*--untypedExpr->get_args().end())->accept( *visitor );
    504522                                } else {                                                                // builtin routines
    505                                         nameExpr->accept( *this );
     523                                        nameExpr->accept( *visitor );
    506524                                        output << "(";
    507525                                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    510528                        } // if
    511529                } else {
    512                         untypedExpr->get_function()->accept( *this );
     530                        untypedExpr->get_function()->accept( *visitor );
    513531                        output << "(";
    514532                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    517535        }
    518536
    519         void CodeGenerator::visit( RangeExpr * rangeExpr ) {
    520                 rangeExpr->get_low()->accept( *this );
     537        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
     538                rangeExpr->get_low()->accept( *visitor );
    521539                output << " ... ";
    522                 rangeExpr->get_high()->accept( *this );
    523         }
    524 
    525         void CodeGenerator::visit( NameExpr * nameExpr ) {
     540                rangeExpr->get_high()->accept( *visitor );
     541        }
     542
     543        void CodeGenerator::postvisit( NameExpr * nameExpr ) {
    526544                extension( nameExpr );
    527545                OperatorInfo opInfo;
     
    534552        }
    535553
    536         void CodeGenerator::visit( AddressExpr * addressExpr ) {
     554        void CodeGenerator::postvisit( AddressExpr * addressExpr ) {
    537555                extension( addressExpr );
    538556                output << "(&";
    539                 addressExpr->arg->accept( *this );
     557                addressExpr->arg->accept( *visitor );
    540558                output << ")";
    541559        }
    542560
    543         void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
     561        void CodeGenerator::postvisit( LabelAddressExpr *addressExpr ) {
    544562                extension( addressExpr );
    545563                output << "(&&" << addressExpr->arg << ")";
    546564        }
    547565
    548         void CodeGenerator::visit( CastExpr * castExpr ) {
     566        void CodeGenerator::postvisit( CastExpr * castExpr ) {
    549567                extension( castExpr );
    550568                output << "(";
     
    559577                        output << ")";
    560578                } // if
    561                 castExpr->get_arg()->accept( *this );
     579                castExpr->get_arg()->accept( *visitor );
    562580                output << ")";
    563581        }
    564582
    565         void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
     583        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    566584                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    567585                extension( castExpr );
    568586                output << "(virtual ";
    569                 castExpr->get_arg()->accept( *this );
     587                castExpr->get_arg()->accept( *visitor );
    570588                output << ")";
    571589        }
    572590
    573         void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
     591        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    574592                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    575593                extension( memberExpr );
    576                 memberExpr->get_aggregate()->accept( *this );
     594                memberExpr->get_aggregate()->accept( *visitor );
    577595                output << ".";
    578                 memberExpr->get_member()->accept( *this );
    579         }
    580 
    581         void CodeGenerator::visit( MemberExpr * memberExpr ) {
     596                memberExpr->get_member()->accept( *visitor );
     597        }
     598
     599        void CodeGenerator::postvisit( MemberExpr * memberExpr ) {
    582600                extension( memberExpr );
    583                 memberExpr->get_aggregate()->accept( *this );
     601                memberExpr->get_aggregate()->accept( *visitor );
    584602                output << "." << mangleName( memberExpr->get_member() );
    585603        }
    586604
    587         void CodeGenerator::visit( VariableExpr * variableExpr ) {
     605        void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
    588606                extension( variableExpr );
    589607                OperatorInfo opInfo;
     
    595613        }
    596614
    597         void CodeGenerator::visit( ConstantExpr * constantExpr ) {
     615        void CodeGenerator::postvisit( ConstantExpr * constantExpr ) {
    598616                assert( constantExpr->get_constant() );
    599617                extension( constantExpr );
    600                 constantExpr->get_constant()->accept( *this );
    601         }
    602 
    603         void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {
     618                constantExpr->get_constant()->accept( *visitor );
     619        }
     620
     621        void CodeGenerator::postvisit( SizeofExpr * sizeofExpr ) {
    604622                extension( sizeofExpr );
    605623                output << "sizeof(";
     
    607625                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    608626                } else {
    609                         sizeofExpr->get_expr()->accept( *this );
     627                        sizeofExpr->get_expr()->accept( *visitor );
    610628                } // if
    611629                output << ")";
    612630        }
    613631
    614         void CodeGenerator::visit( AlignofExpr * alignofExpr ) {
     632        void CodeGenerator::postvisit( AlignofExpr * alignofExpr ) {
    615633                // use GCC extension to avoid bumping std to C11
    616634                extension( alignofExpr );
     
    619637                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    620638                } else {
    621                         alignofExpr->get_expr()->accept( *this );
     639                        alignofExpr->get_expr()->accept( *visitor );
    622640                } // if
    623641                output << ")";
    624642        }
    625643
    626         void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
     644        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    627645                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    628646                output << "offsetof(";
     
    632650        }
    633651
    634         void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {
     652        void CodeGenerator::postvisit( OffsetofExpr * offsetofExpr ) {
    635653                // use GCC builtin
    636654                output << "__builtin_offsetof(";
     
    640658        }
    641659
    642         void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
     660        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    643661                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    644662                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    645663        }
    646664
    647         void CodeGenerator::visit( LogicalExpr * logicalExpr ) {
     665        void CodeGenerator::postvisit( LogicalExpr * logicalExpr ) {
    648666                extension( logicalExpr );
    649667                output << "(";
    650                 logicalExpr->get_arg1()->accept( *this );
     668                logicalExpr->get_arg1()->accept( *visitor );
    651669                if ( logicalExpr->get_isAnd() ) {
    652670                        output << " && ";
     
    654672                        output << " || ";
    655673                } // if
    656                 logicalExpr->get_arg2()->accept( *this );
     674                logicalExpr->get_arg2()->accept( *visitor );
    657675                output << ")";
    658676        }
    659677
    660         void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {
     678        void CodeGenerator::postvisit( ConditionalExpr * conditionalExpr ) {
    661679                extension( conditionalExpr );
    662680                output << "(";
    663                 conditionalExpr->get_arg1()->accept( *this );
     681                conditionalExpr->get_arg1()->accept( *visitor );
    664682                output << " ? ";
    665                 conditionalExpr->get_arg2()->accept( *this );
     683                conditionalExpr->get_arg2()->accept( *visitor );
    666684                output << " : ";
    667                 conditionalExpr->get_arg3()->accept( *this );
     685                conditionalExpr->get_arg3()->accept( *visitor );
    668686                output << ")";
    669687        }
    670688
    671         void CodeGenerator::visit( CommaExpr * commaExpr ) {
     689        void CodeGenerator::postvisit( CommaExpr * commaExpr ) {
    672690                extension( commaExpr );
    673691                output << "(";
     
    676694                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    677695                }
    678                 commaExpr->get_arg1()->accept( *this );
     696                commaExpr->get_arg1()->accept( *visitor );
    679697                output << " , ";
    680                 commaExpr->get_arg2()->accept( *this );
     698                commaExpr->get_arg2()->accept( *visitor );
    681699                output << ")";
    682700        }
    683701
    684         void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
     702        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    685703                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    686                 tupleExpr->stmtExpr->accept( *this );
    687         }
    688 
    689         void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
     704                tupleExpr->stmtExpr->accept( *visitor );
     705        }
     706
     707        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    690708                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    691709                extension( tupleExpr );
     
    695713        }
    696714
    697         void CodeGenerator::visit( TupleExpr * tupleExpr ) {
     715        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    698716                assertf( ! genC, "TupleExpr should not reach code generation." );
    699717                extension( tupleExpr );
     
    703721        }
    704722
    705         void CodeGenerator::visit( TupleIndexExpr * tupleExpr ) {
     723        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    706724                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    707725                extension( tupleExpr );
    708                 tupleExpr->get_tuple()->accept( *this );
     726                tupleExpr->get_tuple()->accept( *visitor );
    709727                output << "." << tupleExpr->get_index();
    710728        }
    711729
    712         void CodeGenerator::visit( TypeExpr * typeExpr ) {
     730        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    713731                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    714732                // assertf( ! genC, "TypeExpr should not reach code generation." );
     
    718736        }
    719737
    720         void CodeGenerator::visit( AsmExpr * asmExpr ) {
     738        void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
    721739                if ( asmExpr->get_inout() ) {
    722740                        output << "[ ";
    723                         asmExpr->get_inout()->accept( *this );
     741                        asmExpr->get_inout()->accept( *visitor );
    724742                        output << " ] ";
    725743                } // if
    726                 asmExpr->get_constraint()->accept( *this );
     744                asmExpr->get_constraint()->accept( *visitor );
    727745                output << " ( ";
    728                 asmExpr->get_operand()->accept( *this );
     746                asmExpr->get_operand()->accept( *visitor );
    729747                output << " )";
    730748        }
    731749
    732         void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
     750        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    733751                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    734752                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    735                 compLitExpr->get_initializer()->accept( *this );
    736         }
    737 
    738         void CodeGenerator::visit( UniqueExpr * unqExpr ) {
     753                compLitExpr->get_initializer()->accept( *visitor );
     754        }
     755
     756        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    739757                assertf( ! genC, "Unique expressions should not reach code generation." );
    740758                output << "unq<" << unqExpr->get_id() << ">{ ";
    741                 unqExpr->get_expr()->accept( *this );
     759                unqExpr->get_expr()->accept( *visitor );
    742760                output << " }";
    743761        }
    744762
    745         void CodeGenerator::visit( StmtExpr * stmtExpr ) {
     763        void CodeGenerator::postvisit( StmtExpr * stmtExpr ) {
    746764                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    747765                updateLocation( stmtExpr );
     
    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 ) {
     861        void CodeGenerator::postvisit( IfStmt * ifStmt ) {
    839862                updateLocation( ifStmt );
    840863                output << "if ( ";
    841                 ifStmt->get_condition()->accept( *this );
     864                ifStmt->get_condition()->accept( *visitor );
    842865                output << " ) ";
    843866
    844                 ifStmt->get_thenPart()->accept( *this );
     867                ifStmt->get_thenPart()->accept( *visitor );
    845868
    846869                if ( ifStmt->get_elsePart() != 0) {
    847870                        output << " else ";
    848                         ifStmt->get_elsePart()->accept( *this );
    849                 } // if
    850         }
    851 
    852         void CodeGenerator::visit( SwitchStmt * switchStmt ) {
     871                        ifStmt->get_elsePart()->accept( *visitor );
     872                } // if
     873        }
     874
     875        void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
    853876                updateLocation( switchStmt );
    854877                output << "switch ( " ;
    855                 switchStmt->get_condition()->accept( *this );
     878                switchStmt->get_condition()->accept( *visitor );
    856879                output << " ) ";
    857880
    858881                output << "{" << std::endl;
    859882                ++indent;
    860                 acceptAll( switchStmt->get_statements(), *this );
     883                acceptAll( switchStmt->get_statements(), *visitor );
    861884                --indent;
    862885                output << indent << "}";
    863886        }
    864887
    865         void CodeGenerator::visit( CaseStmt * caseStmt ) {
     888        void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
    866889                updateLocation( caseStmt );
    867890                if ( caseStmt->isDefault()) {
     
    869892                } else {
    870893                        output << "case ";
    871                         caseStmt->get_condition()->accept( *this );
     894                        caseStmt->get_condition()->accept( *visitor );
    872895                } // if
    873896                output << ":\n";
     
    878901                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    879902                        output << indent << printLabels( (*i)->get_labels() )  ;
    880                         (*i)->accept( *this );
     903                        (*i)->accept( *visitor );
    881904                        output << endl;
    882905                } // for
     
    884907        }
    885908
    886         void CodeGenerator::visit( BranchStmt * branchStmt ) {
     909        void CodeGenerator::postvisit( BranchStmt * branchStmt ) {
    887910                switch ( branchStmt->get_type()) {
    888911                  case BranchStmt::Goto:
     
    892915                                if ( branchStmt->get_computedTarget() != 0 ) {
    893916                                        output << "goto *";
    894                                         branchStmt->get_computedTarget()->accept( *this );
     917                                        branchStmt->get_computedTarget()->accept( *visitor );
    895918                                } // if
    896919                        } // if
     
    906929        }
    907930
    908         void CodeGenerator::visit( ReturnStmt * returnStmt ) {
     931        void CodeGenerator::postvisit( ReturnStmt * returnStmt ) {
    909932                output << "return ";
    910                 maybeAccept( returnStmt->get_expr(), *this );
     933                maybeAccept( returnStmt->get_expr(), *visitor );
    911934                output << ";";
    912935        }
    913936
    914         void CodeGenerator::visit( ThrowStmt * throwStmt ) {
     937        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    915938                assertf( ! genC, "Throw statements should not reach code generation." );
    916939
     
    919942                if (throwStmt->get_expr()) {
    920943                        output << " ";
    921                         throwStmt->get_expr()->accept( *this );
     944                        throwStmt->get_expr()->accept( *visitor );
    922945                }
    923946                if (throwStmt->get_target()) {
    924947                        output << " _At ";
    925                         throwStmt->get_target()->accept( *this );
     948                        throwStmt->get_target()->accept( *visitor );
    926949                }
    927950                output << ";";
    928951        }
    929952
    930         void CodeGenerator::visit( WhileStmt * whileStmt ) {
     953        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
    931954                if ( whileStmt->get_isDoWhile() ) {
    932955                        output << "do" ;
    933956                } else {
    934957                        output << "while (" ;
    935                         whileStmt->get_condition()->accept( *this );
     958                        whileStmt->get_condition()->accept( *visitor );
    936959                        output << ")";
    937960                } // if
     
    939962
    940963                output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
    941                 whileStmt->get_body()->accept( *this );
     964                whileStmt->get_body()->accept( *visitor );
    942965
    943966                output << indent;
     
    945968                if ( whileStmt->get_isDoWhile() ) {
    946969                        output << " while (" ;
    947                         whileStmt->get_condition()->accept( *this );
     970                        whileStmt->get_condition()->accept( *visitor );
    948971                        output << ");";
    949972                } // if
    950973        }
    951974
    952         void CodeGenerator::visit( ForStmt * forStmt ) {
     975        void CodeGenerator::postvisit( ForStmt * forStmt ) {
    953976                // initialization is always hoisted, so don't bother doing anything with that
    954977                output << "for (;";
    955978
    956979                if ( forStmt->get_condition() != 0 ) {
    957                         forStmt->get_condition()->accept( *this );
     980                        forStmt->get_condition()->accept( *visitor );
    958981                } // if
    959982                output << ";";
     
    962985                        // cast the top-level expression to void to reduce gcc warnings.
    963986                        Expression * expr = new CastExpr( forStmt->get_increment() );
    964                         expr->accept( *this );
     987                        expr->accept( *visitor );
    965988                } // if
    966989                output << ") ";
     
    968991                if ( forStmt->get_body() != 0 ) {
    969992                        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 ) {
     993                        forStmt->get_body()->accept( *visitor );
     994                } // if
     995        }
     996
     997        void CodeGenerator::postvisit( __attribute__((unused)) NullStmt * nullStmt ) {
    975998                //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() );
    976999                output << "/* null statement */ ;";
    9771000        }
    9781001
    979         void CodeGenerator::visit( DeclStmt * declStmt ) {
    980                 declStmt->get_decl()->accept( *this );
     1002        void CodeGenerator::postvisit( DeclStmt * declStmt ) {
     1003                declStmt->get_decl()->accept( *visitor );
    9811004
    9821005                if ( doSemicolon( declStmt->get_decl() ) ) {
    9831006                        output << ";";
    9841007                } // if
     1008        }
     1009
     1010        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
     1011                assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1012                stmt->callStmt->accept( *visitor );
    9851013        }
    9861014
  • src/CodeGen/CodeGenerator.h

    re06be49 ra9a4771  
    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 * );
     91                void postvisit( ConstructorExpr * );
    8592
    8693                //*** 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 * );
     94                void postvisit( CompoundStmt * );
     95                void postvisit( ExprStmt * );
     96                void postvisit( AsmStmt * );
     97                void postvisit( AsmDecl * );                            // special: statement in declaration context
     98                void postvisit( IfStmt * );
     99                void postvisit( SwitchStmt * );
     100                void postvisit( CaseStmt * );
     101                void postvisit( BranchStmt * );
     102                void postvisit( ReturnStmt * );
     103                void postvisit( ThrowStmt * );
     104                void postvisit( WhileStmt * );
     105                void postvisit( ForStmt * );
     106                void postvisit( NullStmt * );
     107                void postvisit( DeclStmt * );
     108                void postvisit( ImplicitCtorDtorStmt * );
    101109
    102110                void genAttributes( std::list< Attribute * > & attributes );
     
    140148          if ( begin == end ) return;
    141149                for ( ;; ) {
    142                         (*begin++)->accept( *this );
     150                        (*begin++)->accept( *visitor );
    143151                  if ( begin == end ) break;
    144152                        output << ", ";                                                         // separator
  • src/CodeGen/GenType.cc

    re06be49 ra9a4771  
    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

    re06be49 ra9a4771  
    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 ) ) {
     
    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
  • src/CodeTools/TrackLoc.cc

    re06be49 ra9a4771  
    3333
    3434namespace CodeTools {
    35 
    36         std::ostream & operator<<(std::ostream & out, CodeLocation const & loc) {
    37                 return out << loc.filename << '[' << loc.linenumber << ']';
    38         }
    39 
    4035        class LocationPrinter {
    4136                size_t printLevel;
     
    6964                                }
    7065                                else {
    71                                         std::cerr << "Top level node has no CodeLocation " << name << std::endl;
    72                                         exit(EXIT_FAILURE);
     66                                        assertf( false, "Top level node has no CodeLocation %s", name.c_str() );
    7367                                }
    7468                        }
     
    9589                acceptAll( translationUnit, printer );
    9690        }
    97 
    9891} // namespace CodeTools
    9992
  • src/Common/CodeLocation.h

    re06be49 ra9a4771  
    1616#pragma once
    1717
     18#include <iostream>
    1819#include <string>
    1920
    2021struct CodeLocation {
    21         int linenumber;
    22         std::string filename;
     22        int first_line = -1, first_column = -1, last_line = -1, last_column = -1;
     23        std::string filename = "";
    2324
    2425        /// Create a new unset CodeLocation.
    25                 CodeLocation()
    26                 : linenumber( -1 )
    27                 , filename("")
    28         {}
     26        CodeLocation() = default;
    2927
    3028        /// Create a new CodeLocation with the given values.
    3129        CodeLocation( const char* filename, int lineno )
    32                 : linenumber( lineno )
     30                : first_line( lineno )
    3331                , filename(filename ? filename : "")
    3432        {}
     
    3735
    3836        bool isSet () const {
    39                 return -1 != linenumber;
     37                return -1 != first_line;
    4038        }
    4139
     
    4442        }
    4543
    46         void unset () {
    47                 linenumber = -1;
    48                 filename = "";
    49         }
    50 
    51         // Use field access for set.
    52 
    5344        bool followedBy( CodeLocation const & other, int seperation ) {
    54                 return (linenumber + seperation == other.linenumber &&
     45                return (first_line + seperation == other.first_line &&
    5546                        filename == other.filename);
    5647        }
     
    6556};
    6657
    67 inline std::string to_string( const CodeLocation& location ) {
    68     // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
    69     return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : "";
     58inline std::ostream & operator<<( std::ostream & out, const CodeLocation & location ) {
     59        // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
     60        return location.isSet() ? out << location.filename << ":" << location.first_line << ":1 " : out;
    7061}
    71 
  • src/Common/PassVisitor.h

    re06be49 ra9a4771  
    133133        virtual void visit( OneType *oneType ) override final;
    134134
     135        virtual void visit( Designation *designation ) override final;
    135136        virtual void visit( SingleInit *singleInit ) override final;
    136137        virtual void visit( ListInit *listInit ) override final;
     
    221222        virtual Type* mutate( OneType *oneType ) override final;
    222223
     224        virtual Designation* mutate( Designation *designation ) override final;
    223225        virtual Initializer* mutate( SingleInit *singleInit ) override final;
    224226        virtual Initializer* mutate( ListInit *listInit ) override final;
  • src/Common/PassVisitor.impl.h

    re06be49 ra9a4771  
    19261926}
    19271927
     1928template< typename pass_type >
     1929void PassVisitor< pass_type >::visit( Designation * node ) {
     1930        VISIT_START( node );
     1931
     1932        maybeAccept( node->get_designators(), *this );
     1933
     1934        VISIT_END( node );
     1935}
     1936
     1937template< typename pass_type >
     1938Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
     1939        MUTATE_START( node );
     1940
     1941        maybeMutateRef( node->get_designators(), *this );
     1942
     1943        MUTATE_END( Designation, node );
     1944}
     1945
    19281946//--------------------------------------------------------------------------
    19291947// SingleInit
  • src/Common/SemanticError.cc

    re06be49 ra9a4771  
    4545        using std::to_string;
    4646        for( auto err : errors ) {
    47                 os << to_string( err.location ) << err.description << std::endl;
     47                os << err.location << err.description << std::endl;
    4848        }
    4949}
  • src/Common/SemanticError.h

    re06be49 ra9a4771  
    3232
    3333        void maybeSet( const CodeLocation & location ) {
    34                 if( this->location.linenumber < 0 ) {
     34                if( this->location.isUnset() ) {
    3535                        this->location = location;
    3636                }
  • src/ControlStruct/ExceptTranslate.cc

    re06be49 ra9a4771  
    622622                                assertf(false, "Invalid throw in %s at %i\n",
    623623                                        throwStmt->location.filename.c_str(),
    624                                         throwStmt->location.linenumber);
     624                                        throwStmt->location.first_line);
    625625                                return nullptr;
    626626                        }
     
    633633                                assertf(false, "Invalid throwResume in %s at %i\n",
    634634                                        throwStmt->location.filename.c_str(),
    635                                         throwStmt->location.linenumber);
     635                                        throwStmt->location.first_line);
    636636                                return nullptr;
    637637                        }
  • src/InitTweak/FixInit.cc

    re06be49 ra9a4771  
    105105
    106106                /// collects constructed object decls - used as a base class
    107                 class ObjDeclCollector : public AddStmtVisitor {
    108                   public:
    109                         typedef AddStmtVisitor Parent;
    110                         using Parent::visit;
     107                struct ObjDeclCollector : public WithGuards, public WithShortCircuiting {
    111108                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
    112109                        typedef std::list< ObjectDecl * > ObjectSet;
    113                         virtual void visit( CompoundStmt *compoundStmt ) override;
    114                         virtual void visit( DeclStmt *stmt ) override;
     110                        void previsit( CompoundStmt *compoundStmt );
     111                        void previsit( DeclStmt *stmt );
    115112
    116113                        // don't go into other functions
    117                         virtual void visit( FunctionDecl * ) override {}
     114                        void previsit( FunctionDecl * ) { visit_children = false; }
    118115
    119116                  protected:
     
    139136                }
    140137
    141                 class LabelFinder final : public ObjDeclCollector {
    142                   public:
    143                         typedef ObjDeclCollector Parent;
     138                struct LabelFinder final : public ObjDeclCollector {
    144139                        typedef std::map< Label, ObjectSet > LabelMap;
    145140                        // map of Label -> live variables at that label
    146141                        LabelMap vars;
    147142
    148                         void handleStmt( Statement * stmt );
    149 
    150                         // xxx - This needs to be done better.
    151                         // allow some generalization among different kinds of nodes with with similar parentage (e.g. all
    152                         // expressions, all statements, etc.)  important to have this to provide a single entry point so that as new
    153                         // subclasses are added, there is only one place that the code has to be updated, rather than ensure that
    154                         // every specialized class knows about every new kind of statement that might be added.
    155                         using Parent::visit;
    156                         virtual void visit( CompoundStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    157                         virtual void visit( ExprStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    158                         virtual void visit( AsmStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    159                         virtual void visit( IfStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    160                         virtual void visit( WhileStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    161                         virtual void visit( ForStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    162                         virtual void visit( SwitchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    163                         virtual void visit( CaseStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    164                         virtual void visit( BranchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    165                         virtual void visit( ReturnStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    166                         virtual void visit( TryStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    167                         virtual void visit( CatchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    168                         virtual void visit( FinallyStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    169                         virtual void visit( NullStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    170                         virtual void visit( DeclStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    171                         virtual void visit( ImplicitCtorDtorStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     143                        typedef ObjDeclCollector Parent;
     144                        using Parent::previsit;
     145                        void previsit( Statement * stmt );
     146
     147                        void previsit( CompoundStmt *compoundStmt );
     148                        void previsit( DeclStmt *stmt );
    172149                };
    173150
    174                 class InsertDtors final : public ObjDeclCollector {
    175                 public:
     151                struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd {
    176152                        /// insert destructor calls at the appropriate places.  must happen before CtorInit nodes are removed
    177153                        /// (currently by FixInit)
    178154                        static void insert( std::list< Declaration * > & translationUnit );
    179155
    180                         typedef ObjDeclCollector Parent;
    181156                        typedef std::list< ObjectDecl * > OrderedDecls;
    182157                        typedef std::list< OrderedDecls > OrderedDeclsStack;
    183158
    184                         InsertDtors( LabelFinder & finder ) : finder( finder ), labelVars( finder.vars ) {}
    185 
    186                         using Parent::visit;
    187 
    188                         virtual void visit( ObjectDecl * objDecl ) override;
    189                         virtual void visit( FunctionDecl * funcDecl ) override;
    190 
    191                         virtual void visit( CompoundStmt * compoundStmt ) override;
    192                         virtual void visit( ReturnStmt * returnStmt ) override;
    193                         virtual void visit( BranchStmt * stmt ) override;
     159                        InsertDtors( PassVisitor<LabelFinder> & finder ) : finder( finder ), labelVars( finder.pass.vars ) {}
     160
     161                        typedef ObjDeclCollector Parent;
     162                        using Parent::previsit;
     163
     164                        void previsit( ObjectDecl * objDecl );
     165                        void previsit( FunctionDecl * funcDecl );
     166
     167                        void previsit( CompoundStmt * compoundStmt );
     168                        void postvisit( CompoundStmt * compoundStmt );
     169                        void previsit( ReturnStmt * returnStmt );
     170                        void previsit( BranchStmt * stmt );
    194171                private:
    195172                        void handleGoto( BranchStmt * stmt );
    196173
    197                         LabelFinder & finder;
     174                        PassVisitor<LabelFinder> & finder;
    198175                        LabelFinder::LabelMap & labelVars;
    199176                        OrderedDeclsStack reverseDeclOrder;
     
    333310
    334311                void InsertDtors::insert( std::list< Declaration * > & translationUnit ) {
    335                         LabelFinder finder;
    336                         InsertDtors inserter( finder );
     312                        PassVisitor<LabelFinder> finder;
     313                        PassVisitor<InsertDtors> inserter( finder );
    337314                        acceptAll( translationUnit, inserter );
    338315                }
     
    792769                }
    793770
    794                 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
    795                         ObjectSet prevVars = curVars;
    796                         Parent::visit( compoundStmt );
    797                         curVars = prevVars;
    798                 }
    799 
    800                 void ObjDeclCollector::visit( DeclStmt * stmt ) {
     771                void ObjDeclCollector::previsit( CompoundStmt * ) {
     772                        GuardValue( curVars );
     773                }
     774
     775                void ObjDeclCollector::previsit( DeclStmt * stmt ) {
    801776                        // keep track of all variables currently in scope
    802777                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    803778                                curVars.push_back( objDecl );
    804779                        } // if
    805                         Parent::visit( stmt );
    806                 }
    807 
    808                 void LabelFinder::handleStmt( Statement * stmt ) {
     780                }
     781
     782                void LabelFinder::previsit( Statement * stmt ) {
    809783                        // for each label, remember the variables in scope at that label.
    810784                        for ( Label l : stmt->get_labels() ) {
     
    812786                        } // for
    813787                }
     788
     789                void LabelFinder::previsit( CompoundStmt * stmt ) {
     790                        previsit( (Statement *)stmt );
     791                        Parent::previsit( stmt );
     792                }
     793
     794                void LabelFinder::previsit( DeclStmt * stmt ) {
     795                        previsit( (Statement *)stmt );
     796                        Parent::previsit( stmt );
     797                }
     798
    814799
    815800                template<typename Iterator, typename OutputIterator>
     
    827812                }
    828813
    829                 void InsertDtors::visit( ObjectDecl * objDecl ) {
     814                void InsertDtors::previsit( ObjectDecl * objDecl ) {
    830815                        // remember non-static destructed objects so that their destructors can be inserted later
    831816                        if ( ! objDecl->get_storageClasses().is_static ) {
     
    841826                                } // if
    842827                        } // if
    843                         Parent::visit( objDecl );
    844                 }
    845 
    846                 template< typename Visitor >
    847                 void handleFuncDecl( FunctionDecl * funcDecl, Visitor & visitor ) {
    848                         maybeAccept( funcDecl->get_functionType(), visitor );
    849                         maybeAccept( funcDecl->get_statements(), visitor );
    850                 }
    851 
    852                 void InsertDtors::visit( FunctionDecl * funcDecl ) {
     828                }
     829
     830                void InsertDtors::previsit( FunctionDecl * funcDecl ) {
    853831                        // each function needs to have its own set of labels
    854                         ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars );
     832                        GuardValue( labelVars );
    855833                        labelVars.clear();
    856                         handleFuncDecl( funcDecl, finder );
    857 
    858                         // all labels for this function have been collected, insert destructors as appropriate.
    859                         // can't be Parent::mutate, because ObjDeclCollector bottoms out on FunctionDecl
    860                         handleFuncDecl( funcDecl, *this );
    861                 }
    862 
    863                 void InsertDtors::visit( CompoundStmt * compoundStmt ) {
     834                        maybeAccept( funcDecl->type, finder );
     835                        maybeAccept( funcDecl->statements, finder );
     836
     837                        // all labels for this function have been collected, insert destructors as appropriate via implicit recursion.
     838                }
     839
     840                void InsertDtors::previsit( CompoundStmt * compoundStmt ) {
    864841                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
    865842                        // when block is left, just the destructors associated with variables defined in this block, so push a new
    866843                        // list to the top of the stack so that we can differentiate scopes
    867844                        reverseDeclOrder.push_front( OrderedDecls() );
    868                         Parent::visit( compoundStmt );
    869 
     845                        Parent::previsit( compoundStmt );
     846                }
     847
     848                void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
    870849                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
    871850                        // causes unreachable code warnings
     
    877856                }
    878857
    879                 void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
     858                void InsertDtors::previsit( ReturnStmt * ) {
    880859                        // return exits all scopes, so dump destructors for all scopes
    881860                        for ( OrderedDecls & od : reverseDeclOrder ) {
    882                                 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );
     861                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
    883862                        } // for
    884863                }
     
    928907                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    929908                                } // for
    930                                 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
     909                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
    931910                        } // if
    932911                }
    933912
    934                 void InsertDtors::visit( BranchStmt * stmt ) {
     913                void InsertDtors::previsit( BranchStmt * stmt ) {
    935914                        switch( stmt->get_type() ) {
    936915                          case BranchStmt::Continue:
  • src/Parser/ParseNode.h

    re06be49 ra9a4771  
    4444//##############################################################################
    4545
     46typedef CodeLocation YYLTYPE;
     47#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
     48
    4649extern char * yyfilename;
    4750extern int yylineno;
     51extern YYLTYPE yylloc;
    4852
    4953class ParseNode {
     
    7377        ParseNode * next = nullptr;
    7478        std::string * name = nullptr;
    75         CodeLocation location = { yyfilename, yylineno };
     79        CodeLocation location = yylloc;
    7680}; // ParseNode
    7781
  • src/Parser/lex.ll

    re06be49 ra9a4771  
    2626
    2727unsigned int column = 0;                                                                // position of the end of the last token parsed
    28 #define YY_USER_ACTION column += yyleng;                                // trigger before each matching rule's action
     28#define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";                          // trigger before each matching rule's action
    2929
    3030#include <string>
  • src/Parser/parser.yy

    re06be49 ra9a4771  
    116116
    117117bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
     118
     119# define YYLLOC_DEFAULT(Cur, Rhs, N)                            \
     120do                                                              \
     121        if (N) {                                                      \
     122                (Cur).first_line   = YYRHSLOC(Rhs, 1).first_line;           \
     123                (Cur).first_column = YYRHSLOC(Rhs, 1).first_column;         \
     124                (Cur).last_line    = YYRHSLOC(Rhs, N).last_line;            \
     125                (Cur).last_column  = YYRHSLOC(Rhs, N).last_column;          \
     126                (Cur).filename     = YYRHSLOC(Rhs, 1).filename;             \
     127        } else {                                                      \
     128                (Cur).first_line   = (Cur).last_line   =                    \
     129                        YYRHSLOC(Rhs, 0).last_line;                               \
     130                (Cur).first_column = (Cur).last_column =                    \
     131                        YYRHSLOC(Rhs, 0).last_column;                             \
     132                (Cur).filename     = YYRHSLOC(Rhs, 0).filename;             \
     133        }                                                             \
     134while (0)
    118135%}
    119136
     
    346363%precedence ELSE        // token precedence for start of else clause in IF/WAITFOR statement
    347364
     365%locations
    348366
    349367%start translation_unit                                                                 // parse-tree root
  • src/SymTab/Autogen.cc

    re06be49 ra9a4771  
    223223                        FunctionType * ftype = data.genType( refType );
    224224
    225                         if(concurrent_type && CodeGen::isDestructor( data.fname )) {
     225                        if ( concurrent_type && CodeGen::isDestructor( data.fname ) ) {
    226226                                ftype->parameters.front()->get_type()->set_mutex( true );
    227227                        }
  • src/SynTree/BaseSyntaxNode.h

    re06be49 ra9a4771  
    2626
    2727        virtual void accept( Visitor & v ) = 0;
     28  virtual void print( std::ostream & os, int indent = 0 ) const = 0;
    2829};
    2930
  • src/tests/.expect/dtor-early-exit-ERR1.txt

    re06be49 ra9a4771  
    1 dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:153:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
    22  with target: L1
    33  with original target: L1
  • src/tests/.expect/dtor-early-exit-ERR2.txt

    re06be49 ra9a4771  
    1 dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
    22  with target: L2
    33  with original target: L2
Note: See TracChangeset for help on using the changeset viewer.