Changes in / [47b5b63:39fea2f]


Ignore:
Location:
src
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r47b5b63 r39fea2f  
    7979        }
    8080
    81         /* Using updateLocation at the beginning of a node and endl
     81        /* Using updateLocation at the beginning of a node and nextLine
    8282         * within a node should become the method of formating.
    8383         */
    8484        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    85                 // skip if linemarks shouldn't appear or if codelocation is unset
    86                 if ( !lineMarks || to.isUnset() ) return;
    87 
    88                 if ( currentLocation.followedBy( to, 0 ) ) {
     85                if ( !lineMarks ) {
     86                        return;
     87                } else if ( currentLocation.followedBy( to, 0 ) ) {
    8988                        return;
    9089                } else if ( currentLocation.followedBy( to, 1 ) ) {
    9190                        output << "\n" << indent;
    92                         currentLocation.first_line += 1;
     91                        currentLocation.linenumber += 1;
    9392                } else if ( currentLocation.followedBy( to, 2 ) ) {
    9493                        output << "\n\n" << indent;
    95                         currentLocation.first_line += 2;
    96                 } else {
    97                         output << "\n# " << to.first_line << " \"" << to.filename
     94                        currentLocation.linenumber += 2;
     95                } else {
     96                        output << "\n# " << to.linenumber << " \"" << to.filename
    9897                               << "\"\n" << indent;
    9998                        currentLocation = to;
     
    106105        }
    107106
    108         // replace endl
    109         ostream & CodeGenerator::LineEnder::operator()( ostream & os ) const {
    110                 // if ( !cg.lineMarks ) {
    111                 //      os << "\n" << cg.indent << std::flush;
    112                 // }
    113                 os << "\n" << std::flush;
    114                 cg.currentLocation.first_line++;
    115                 // os << "/* did endl; current loc is: " << cg.currentLocation.first_line << "*/";
    116                 return os;
    117         }
    118 
    119         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), endl( *this ) {}
     107        void CodeGenerator::nextLine() {
     108                if ( !lineMarks ) {
     109                        output << "\n" << indent << std::flush;
     110                }
     111        }
     112
     113        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
    120114
    121115        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
     
    145139        } // CodeGenerator::genAttributes
    146140
    147         // *** BaseSyntaxNode
    148         void CodeGenerator::previsit( BaseSyntaxNode * node ) {
    149                 // turn off automatic recursion for all nodes, to allow each visitor to
    150                 // precisely control the order in which its children are visited.
    151                 visit_children = false;
    152                 updateLocation( node );
    153         }
    154 
    155         // *** BaseSyntaxNode
    156         void CodeGenerator::postvisit( BaseSyntaxNode * node ) {
    157                 std::stringstream ss;
    158                 node->print( ss );
    159                 assertf( false, "Unhandled node reached in CodeGenerator: %s", ss.str().c_str() );
    160         }
    161141
    162142        // *** Declarations
    163         void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
     143        void CodeGenerator::visit( FunctionDecl * functionDecl ) {
    164144                extension( functionDecl );
    165145                genAttributes( functionDecl->get_attributes() );
     
    172152                asmName( functionDecl );
    173153
     154                // acceptAll( functionDecl->get_oldDecls(), *this );
    174155                if ( functionDecl->get_statements() ) {
    175                         functionDecl->get_statements()->accept( *visitor );
    176                 } // if
    177         }
    178 
    179         void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
     156                        functionDecl->get_statements()->accept( *this );
     157                } // if
     158        }
     159
     160        void CodeGenerator::visit( ObjectDecl * objectDecl ) {
    180161                if (objectDecl->get_name().empty() && genC ) {
    181162                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    194175                if ( objectDecl->get_init() ) {
    195176                        output << " = ";
    196                         objectDecl->get_init()->accept( *visitor );
     177                        objectDecl->get_init()->accept( *this );
    197178                } // if
    198179
    199180                if ( objectDecl->get_bitfieldWidth() ) {
    200181                        output << ":";
    201                         objectDecl->get_bitfieldWidth()->accept( *visitor );
     182                        objectDecl->get_bitfieldWidth()->accept( *this );
    202183                } // if
    203184        }
     
    222203                        ++indent;
    223204                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
     205                                updateLocation( *i );
    224206                                output << indent;
    225                                 (*i)->accept( *visitor );
     207                                (*i)->accept( *this );
    226208                                output << ";" << endl;
    227209                        } // for
     
    233215        }
    234216
    235         void CodeGenerator::postvisit( StructDecl * structDecl ) {
     217        void CodeGenerator::visit( StructDecl * structDecl ) {
    236218                extension( structDecl );
    237219                handleAggregate( structDecl, "struct " );
    238220        }
    239221
    240         void CodeGenerator::postvisit( UnionDecl * unionDecl ) {
     222        void CodeGenerator::visit( UnionDecl * unionDecl ) {
    241223                extension( unionDecl );
    242224                handleAggregate( unionDecl, "union " );
    243225        }
    244226
    245         void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
     227        void CodeGenerator::visit( EnumDecl * enumDecl ) {
    246228                extension( enumDecl );
     229                updateLocation( enumDecl );
    247230                output << "enum ";
    248231                genAttributes( enumDecl->get_attributes() );
     
    259242                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    260243                                assert( obj );
     244                                updateLocation( obj );
    261245                                output << indent << mangleName( obj );
    262246                                if ( obj->get_init() ) {
    263247                                        output << " = ";
    264                                         obj->get_init()->accept( *visitor );
     248                                        obj->get_init()->accept( *this );
    265249                                } // if
    266250                                output << "," << endl;
     
    273257        }
    274258
    275         void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
     259        void CodeGenerator::visit( TraitDecl * traitDecl ) {
    276260                assertf( ! genC, "TraitDecls should not reach code generation." );
    277261                extension( traitDecl );
     
    279263        }
    280264
    281         void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
     265        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    282266                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     267                updateLocation( typeDecl );
    283268                output << "typedef ";
    284269                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    285270        }
    286271
    287         void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
     272        void CodeGenerator::visit( TypeDecl * typeDecl ) {
    288273                assertf( ! genC, "TypeDecls should not reach code generation." );
    289274                output << typeDecl->genTypeString() << " " << typeDecl->get_name();
     
    298283        }
    299284
    300         void CodeGenerator::postvisit( Designation * designation ) {
     285        void CodeGenerator::visit( Designation * designation ) {
    301286                std::list< Expression * > designators = designation->get_designators();
    302287                if ( designators.size() == 0 ) return;
     
    305290                                // if expression is a NameExpr or VariableExpr, then initializing aggregate member
    306291                                output << ".";
    307                                 des->accept( *visitor );
     292                                des->accept( *this );
    308293                        } else {
    309294                                // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
    310295                                output << "[";
    311                                 des->accept( *visitor );
     296                                des->accept( *this );
    312297                                output << "]";
    313298                        } // if
     
    316301        }
    317302
    318         void CodeGenerator::postvisit( SingleInit * init ) {
    319                 init->get_value()->accept( *visitor );
    320         }
    321 
    322         void CodeGenerator::postvisit( ListInit * init ) {
     303        void CodeGenerator::visit( SingleInit * init ) {
     304                init->get_value()->accept( *this );
     305        }
     306
     307        void CodeGenerator::visit( ListInit * init ) {
    323308                auto initBegin = init->begin();
    324309                auto initEnd = init->end();
     
    328313                output << "{ ";
    329314                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
    330                         (*desigBegin)->accept( *visitor );
    331                         (*initBegin)->accept( *visitor );
     315                        (*desigBegin)->accept( *this );
     316                        (*initBegin)->accept( *this );
    332317                        ++initBegin, ++desigBegin;
    333318                        if ( initBegin != initEnd ) {
     
    339324        }
    340325
    341         void CodeGenerator::postvisit( ConstructorInit * init ){
     326        void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
    342327                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    343328                // pseudo-output for constructor/destructor pairs
    344                 output << "<ctorinit>{" << endl << ++indent << "ctor: ";
    345                 maybeAccept( init->get_ctor(), *visitor );
    346                 output << ", " << endl << indent << "dtor: ";
    347                 maybeAccept( init->get_dtor(), *visitor );
    348                 output << endl << --indent << "}";
    349         }
    350 
    351         void CodeGenerator::postvisit( Constant * constant ) {
     329                output << "<ctorinit>{" << std::endl << ++indent << "ctor: ";
     330                maybeAccept( init->get_ctor(), *this );
     331                output << ", " << std::endl << indent << "dtor: ";
     332                maybeAccept( init->get_dtor(), *this );
     333                output << std::endl << --indent << "}";
     334        }
     335
     336        void CodeGenerator::visit( Constant * constant ) {
    352337                output << constant->get_value() ;
    353338        }
    354339
    355340        // *** Expressions
    356         void CodeGenerator::postvisit( ApplicationExpr * applicationExpr ) {
     341        void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {
    357342                extension( applicationExpr );
    358343                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
     
    363348                                  case OT_INDEX:
    364349                                        assert( applicationExpr->get_args().size() == 2 );
    365                                         (*arg++)->accept( *visitor );
     350                                        (*arg++)->accept( *this );
    366351                                        output << "[";
    367                                         (*arg)->accept( *visitor );
     352                                        (*arg)->accept( *this );
    368353                                        output << "]";
    369354                                        break;
     
    380365                                                // effects, so must still output this expression
    381366                                                output << "(";
    382                                                 (*arg++)->accept( *visitor );
     367                                                (*arg++)->accept( *this );
    383368                                                output << ") /* " << opInfo.inputName << " */";
    384369                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    385370                                                // intrinsic two parameter constructors are essentially bitwise assignment
    386371                                                output << "(";
    387                                                 (*arg++)->accept( *visitor );
     372                                                (*arg++)->accept( *this );
    388373                                                output << opInfo.symbol;
    389                                                 (*arg)->accept( *visitor );
     374                                                (*arg)->accept( *this );
    390375                                                output << ") /* " << opInfo.inputName << " */";
    391376                                        } else {
     
    400385                                        output << "(";
    401386                                        output << opInfo.symbol;
    402                                         (*arg)->accept( *visitor );
     387                                        (*arg)->accept( *this );
    403388                                        output << ")";
    404389                                        break;
     
    407392                                  case OT_POSTFIXASSIGN:
    408393                                        assert( applicationExpr->get_args().size() == 1 );
    409                                         (*arg)->accept( *visitor );
     394                                        (*arg)->accept( *this );
    410395                                        output << opInfo.symbol;
    411396                                        break;
     
    416401                                        assert( applicationExpr->get_args().size() == 2 );
    417402                                        output << "(";
    418                                         (*arg++)->accept( *visitor );
     403                                        (*arg++)->accept( *this );
    419404                                        output << opInfo.symbol;
    420                                         (*arg)->accept( *visitor );
     405                                        (*arg)->accept( *this );
    421406                                        output << ")";
    422407                                        break;
     
    428413                                } // switch
    429414                        } else {
    430                                 varExpr->accept( *visitor );
     415                                varExpr->accept( *this );
    431416                                output << "(";
    432417                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    434419                        } // if
    435420                } else {
    436                         applicationExpr->get_function()->accept( *visitor );
     421                        applicationExpr->get_function()->accept( *this );
    437422                        output << "(";
    438423                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    441426        }
    442427
    443         void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
     428        void CodeGenerator::visit( UntypedExpr * untypedExpr ) {
    444429                extension( untypedExpr );
    445430                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    450435                                  case OT_INDEX:
    451436                                        assert( untypedExpr->get_args().size() == 2 );
    452                                         (*arg++)->accept( *visitor );
     437                                        (*arg++)->accept( *this );
    453438                                        output << "[";
    454                                         (*arg)->accept( *visitor );
     439                                        (*arg)->accept( *this );
    455440                                        output << "]";
    456441                                        break;
     
    465450                                                // effects, so must still output this expression
    466451                                                output << "(";
    467                                                 (*arg++)->accept( *visitor );
     452                                                (*arg++)->accept( *this );
    468453                                                output << ") /* " << opInfo.inputName << " */";
    469454                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    470455                                                // intrinsic two parameter constructors are essentially bitwise assignment
    471456                                                output << "(";
    472                                                 (*arg++)->accept( *visitor );
     457                                                (*arg++)->accept( *this );
    473458                                                output << opInfo.symbol;
    474                                                 (*arg)->accept( *visitor );
     459                                                (*arg)->accept( *this );
    475460                                                output << ") /* " << opInfo.inputName << " */";
    476461                                        } else {
    477462                                                // no constructors with 0 or more than 2 parameters
    478                                                 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    479                                                 output << "(";
    480                                                 (*arg++)->accept( *visitor );
    481                                                 output << opInfo.symbol << "{ ";
    482                                                 genCommaList( arg, untypedExpr->get_args().end() );
    483                                                 output << "}) /* " << opInfo.inputName << " */";
     463                                                assert( false );
    484464                                        } // if
    485465                                        break;
     
    491471                                        output << "(";
    492472                                        output << opInfo.symbol;
    493                                         (*arg)->accept( *visitor );
     473                                        (*arg)->accept( *this );
    494474                                        output << ")";
    495475                                        break;
     
    498478                                  case OT_POSTFIXASSIGN:
    499479                                        assert( untypedExpr->get_args().size() == 1 );
    500                                         (*arg)->accept( *visitor );
     480                                        (*arg)->accept( *this );
    501481                                        output << opInfo.symbol;
    502482                                        break;
     
    506486                                        assert( untypedExpr->get_args().size() == 2 );
    507487                                        output << "(";
    508                                         (*arg++)->accept( *visitor );
     488                                        (*arg++)->accept( *this );
    509489                                        output << opInfo.symbol;
    510                                         (*arg)->accept( *visitor );
     490                                        (*arg)->accept( *this );
    511491                                        output << ")";
    512492                                        break;
     
    519499                                if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    520500                                        assert( untypedExpr->get_args().size() == 2 );
    521                                         (*untypedExpr->get_args().begin())->accept( *visitor );
     501                                        (*untypedExpr->get_args().begin())->accept( *this );
    522502                                        output << " ... ";
    523                                         (*--untypedExpr->get_args().end())->accept( *visitor );
     503                                        (*--untypedExpr->get_args().end())->accept( *this );
    524504                                } else {                                                                // builtin routines
    525                                         nameExpr->accept( *visitor );
     505                                        nameExpr->accept( *this );
    526506                                        output << "(";
    527507                                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    530510                        } // if
    531511                } else {
    532                         untypedExpr->get_function()->accept( *visitor );
     512                        untypedExpr->get_function()->accept( *this );
    533513                        output << "(";
    534514                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    537517        }
    538518
    539         void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
    540                 rangeExpr->get_low()->accept( *visitor );
     519        void CodeGenerator::visit( RangeExpr * rangeExpr ) {
     520                rangeExpr->get_low()->accept( *this );
    541521                output << " ... ";
    542                 rangeExpr->get_high()->accept( *visitor );
    543         }
    544 
    545         void CodeGenerator::postvisit( NameExpr * nameExpr ) {
     522                rangeExpr->get_high()->accept( *this );
     523        }
     524
     525        void CodeGenerator::visit( NameExpr * nameExpr ) {
    546526                extension( nameExpr );
    547527                OperatorInfo opInfo;
     
    554534        }
    555535
    556         void CodeGenerator::postvisit( AddressExpr * addressExpr ) {
     536        void CodeGenerator::visit( AddressExpr * addressExpr ) {
    557537                extension( addressExpr );
    558538                output << "(&";
    559                 addressExpr->arg->accept( *visitor );
     539                addressExpr->arg->accept( *this );
    560540                output << ")";
    561541        }
    562542
    563         void CodeGenerator::postvisit( LabelAddressExpr *addressExpr ) {
     543        void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
    564544                extension( addressExpr );
    565545                output << "(&&" << addressExpr->arg << ")";
    566546        }
    567547
    568         void CodeGenerator::postvisit( CastExpr * castExpr ) {
     548        void CodeGenerator::visit( CastExpr * castExpr ) {
    569549                extension( castExpr );
    570550                output << "(";
     
    579559                        output << ")";
    580560                } // if
    581                 castExpr->get_arg()->accept( *visitor );
     561                castExpr->get_arg()->accept( *this );
    582562                output << ")";
    583563        }
    584564
    585         void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
     565        void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
    586566                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    587567                extension( castExpr );
    588568                output << "(virtual ";
    589                 castExpr->get_arg()->accept( *visitor );
     569                castExpr->get_arg()->accept( *this );
    590570                output << ")";
    591571        }
    592572
    593         void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
     573        void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
    594574                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    595575                extension( memberExpr );
    596                 memberExpr->get_aggregate()->accept( *visitor );
     576                memberExpr->get_aggregate()->accept( *this );
    597577                output << ".";
    598                 memberExpr->get_member()->accept( *visitor );
    599         }
    600 
    601         void CodeGenerator::postvisit( MemberExpr * memberExpr ) {
     578                memberExpr->get_member()->accept( *this );
     579        }
     580
     581        void CodeGenerator::visit( MemberExpr * memberExpr ) {
    602582                extension( memberExpr );
    603                 memberExpr->get_aggregate()->accept( *visitor );
     583                memberExpr->get_aggregate()->accept( *this );
    604584                output << "." << mangleName( memberExpr->get_member() );
    605585        }
    606586
    607         void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
     587        void CodeGenerator::visit( VariableExpr * variableExpr ) {
    608588                extension( variableExpr );
    609589                OperatorInfo opInfo;
     
    615595        }
    616596
    617         void CodeGenerator::postvisit( ConstantExpr * constantExpr ) {
     597        void CodeGenerator::visit( ConstantExpr * constantExpr ) {
    618598                assert( constantExpr->get_constant() );
    619599                extension( constantExpr );
    620                 constantExpr->get_constant()->accept( *visitor );
    621         }
    622 
    623         void CodeGenerator::postvisit( SizeofExpr * sizeofExpr ) {
     600                constantExpr->get_constant()->accept( *this );
     601        }
     602
     603        void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {
    624604                extension( sizeofExpr );
    625605                output << "sizeof(";
     
    627607                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    628608                } else {
    629                         sizeofExpr->get_expr()->accept( *visitor );
     609                        sizeofExpr->get_expr()->accept( *this );
    630610                } // if
    631611                output << ")";
    632612        }
    633613
    634         void CodeGenerator::postvisit( AlignofExpr * alignofExpr ) {
     614        void CodeGenerator::visit( AlignofExpr * alignofExpr ) {
    635615                // use GCC extension to avoid bumping std to C11
    636616                extension( alignofExpr );
     
    639619                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    640620                } else {
    641                         alignofExpr->get_expr()->accept( *visitor );
     621                        alignofExpr->get_expr()->accept( *this );
    642622                } // if
    643623                output << ")";
    644624        }
    645625
    646         void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
     626        void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
    647627                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    648628                output << "offsetof(";
     
    652632        }
    653633
    654         void CodeGenerator::postvisit( OffsetofExpr * offsetofExpr ) {
     634        void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {
    655635                // use GCC builtin
    656636                output << "__builtin_offsetof(";
     
    660640        }
    661641
    662         void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
     642        void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
    663643                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    664644                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    665645        }
    666646
    667         void CodeGenerator::postvisit( LogicalExpr * logicalExpr ) {
     647        void CodeGenerator::visit( LogicalExpr * logicalExpr ) {
    668648                extension( logicalExpr );
    669649                output << "(";
    670                 logicalExpr->get_arg1()->accept( *visitor );
     650                logicalExpr->get_arg1()->accept( *this );
    671651                if ( logicalExpr->get_isAnd() ) {
    672652                        output << " && ";
     
    674654                        output << " || ";
    675655                } // if
    676                 logicalExpr->get_arg2()->accept( *visitor );
     656                logicalExpr->get_arg2()->accept( *this );
    677657                output << ")";
    678658        }
    679659
    680         void CodeGenerator::postvisit( ConditionalExpr * conditionalExpr ) {
     660        void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {
    681661                extension( conditionalExpr );
    682662                output << "(";
    683                 conditionalExpr->get_arg1()->accept( *visitor );
     663                conditionalExpr->get_arg1()->accept( *this );
    684664                output << " ? ";
    685                 conditionalExpr->get_arg2()->accept( *visitor );
     665                conditionalExpr->get_arg2()->accept( *this );
    686666                output << " : ";
    687                 conditionalExpr->get_arg3()->accept( *visitor );
     667                conditionalExpr->get_arg3()->accept( *this );
    688668                output << ")";
    689669        }
    690670
    691         void CodeGenerator::postvisit( CommaExpr * commaExpr ) {
     671        void CodeGenerator::visit( CommaExpr * commaExpr ) {
    692672                extension( commaExpr );
    693673                output << "(";
     
    696676                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    697677                }
    698                 commaExpr->get_arg1()->accept( *visitor );
     678                commaExpr->get_arg1()->accept( *this );
    699679                output << " , ";
    700                 commaExpr->get_arg2()->accept( *visitor );
     680                commaExpr->get_arg2()->accept( *this );
    701681                output << ")";
    702682        }
    703683
    704         void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
     684        void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
    705685                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    706                 tupleExpr->stmtExpr->accept( *visitor );
    707         }
    708 
    709         void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
     686                tupleExpr->stmtExpr->accept( *this );
     687        }
     688
     689        void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
    710690                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    711691                extension( tupleExpr );
     
    715695        }
    716696
    717         void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
     697        void CodeGenerator::visit( TupleExpr * tupleExpr ) {
    718698                assertf( ! genC, "TupleExpr should not reach code generation." );
    719699                extension( tupleExpr );
     
    723703        }
    724704
    725         void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
     705        void CodeGenerator::visit( TupleIndexExpr * tupleExpr ) {
    726706                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    727707                extension( tupleExpr );
    728                 tupleExpr->get_tuple()->accept( *visitor );
     708                tupleExpr->get_tuple()->accept( *this );
    729709                output << "." << tupleExpr->get_index();
    730710        }
    731711
    732         void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
     712        void CodeGenerator::visit( TypeExpr * typeExpr ) {
    733713                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    734714                // assertf( ! genC, "TypeExpr should not reach code generation." );
     
    738718        }
    739719
    740         void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
     720        void CodeGenerator::visit( AsmExpr * asmExpr ) {
    741721                if ( asmExpr->get_inout() ) {
    742722                        output << "[ ";
    743                         asmExpr->get_inout()->accept( *visitor );
     723                        asmExpr->get_inout()->accept( *this );
    744724                        output << " ] ";
    745725                } // if
    746                 asmExpr->get_constraint()->accept( *visitor );
     726                asmExpr->get_constraint()->accept( *this );
    747727                output << " ( ";
    748                 asmExpr->get_operand()->accept( *visitor );
     728                asmExpr->get_operand()->accept( *this );
    749729                output << " )";
    750730        }
    751731
    752         void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
     732        void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
    753733                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    754734                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    755                 compLitExpr->get_initializer()->accept( *visitor );
    756         }
    757 
    758         void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
     735                compLitExpr->get_initializer()->accept( *this );
     736        }
     737
     738        void CodeGenerator::visit( UniqueExpr * unqExpr ) {
    759739                assertf( ! genC, "Unique expressions should not reach code generation." );
    760740                output << "unq<" << unqExpr->get_id() << ">{ ";
    761                 unqExpr->get_expr()->accept( *visitor );
     741                unqExpr->get_expr()->accept( *this );
    762742                output << " }";
    763743        }
    764744
    765         void CodeGenerator::postvisit( StmtExpr * stmtExpr ) {
     745        void CodeGenerator::visit( StmtExpr * stmtExpr ) {
    766746                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    767                 output << "({" << endl;
     747                updateLocation( stmtExpr );
     748                output << "({" << std::endl;
    768749                ++indent;
    769750                unsigned int numStmts = stmts.size();
    770751                unsigned int i = 0;
    771752                for ( Statement * stmt : stmts ) {
     753                        updateLocation( stmt );
    772754                        output << indent << printLabels( stmt->get_labels() );
    773755                        if ( i+1 == numStmts ) {
     
    775757                                // cannot cast to void, otherwise the expression statement has no value
    776758                                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    777                                         exprStmt->get_expr()->accept( *visitor );
     759                                        exprStmt->get_expr()->accept( *this );
    778760                                        output << ";" << endl;
    779761                                        ++i;
     
    781763                                }
    782764                        }
    783                         stmt->accept( *visitor );
     765                        stmt->accept( *this );
    784766                        output << endl;
    785767                        if ( wantSpacing( stmt ) ) {
     
    792774        }
    793775
    794         void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    795                 assertf( ! genC, "Unique expressions should not reach code generation." );
    796                 expr->callExpr->accept( *visitor );
    797         }
    798 
    799776        // *** Statements
    800         void CodeGenerator::postvisit( CompoundStmt * compoundStmt ) {
     777        void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
    801778                std::list<Statement*> ks = compoundStmt->get_kids();
    802779                output << "{" << endl;
     
    806783                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++ ) {
    807784                        output << indent << printLabels( (*i)->get_labels() );
    808                         (*i)->accept( *visitor );
     785                        (*i)->accept( *this );
    809786
    810787                        output << endl;
     
    818795        }
    819796
    820         void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
     797        void CodeGenerator::visit( ExprStmt * exprStmt ) {
    821798                assert( exprStmt );
    822799                if ( genC ) {
     
    824801                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
    825802                }
    826                 exprStmt->get_expr()->accept( *visitor );
     803                exprStmt->get_expr()->accept( *this );
    827804                output << ";";
    828805        }
    829806
    830         void CodeGenerator::postvisit( AsmStmt * asmStmt ) {
     807        void CodeGenerator::visit( AsmStmt * asmStmt ) {
    831808                output << "asm ";
    832809                if ( asmStmt->get_voltile() ) output << "volatile ";
    833810                if ( ! asmStmt->get_gotolabels().empty()  ) output << "goto ";
    834811                output << "( ";
    835                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
     812                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
    836813                output << " : ";
    837814                genCommaList( asmStmt->get_output().begin(), asmStmt->get_output().end() );
     
    851828        }
    852829
    853         void CodeGenerator::postvisit( AsmDecl * asmDecl ) {
     830        void CodeGenerator::visit( AsmDecl * asmDecl ) {
    854831                output << "asm ";
    855832                AsmStmt * asmStmt = asmDecl->get_stmt();
    856833                output << "( ";
    857                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
     834                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
    858835                output << " )" ;
    859836        }
    860837
    861         void CodeGenerator::postvisit( IfStmt * ifStmt ) {
     838        void CodeGenerator::visit( IfStmt * ifStmt ) {
     839                updateLocation( ifStmt );
    862840                output << "if ( ";
    863                 ifStmt->get_condition()->accept( *visitor );
     841                ifStmt->get_condition()->accept( *this );
    864842                output << " ) ";
    865843
    866                 ifStmt->get_thenPart()->accept( *visitor );
     844                ifStmt->get_thenPart()->accept( *this );
    867845
    868846                if ( ifStmt->get_elsePart() != 0) {
    869847                        output << " else ";
    870                         ifStmt->get_elsePart()->accept( *visitor );
    871                 } // if
    872         }
    873 
    874         void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
     848                        ifStmt->get_elsePart()->accept( *this );
     849                } // if
     850        }
     851
     852        void CodeGenerator::visit( SwitchStmt * switchStmt ) {
     853                updateLocation( switchStmt );
    875854                output << "switch ( " ;
    876                 switchStmt->get_condition()->accept( *visitor );
     855                switchStmt->get_condition()->accept( *this );
    877856                output << " ) ";
    878857
    879                 output << "{" << endl;
     858                output << "{" << std::endl;
    880859                ++indent;
    881                 acceptAll( switchStmt->get_statements(), *visitor );
     860                acceptAll( switchStmt->get_statements(), *this );
    882861                --indent;
    883862                output << indent << "}";
    884863        }
    885864
    886         void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
     865        void CodeGenerator::visit( CaseStmt * caseStmt ) {
     866                updateLocation( caseStmt );
    887867                if ( caseStmt->isDefault()) {
    888868                        output << "default";
    889869                } else {
    890870                        output << "case ";
    891                         caseStmt->get_condition()->accept( *visitor );
    892                 } // if
    893                 output << ":" << endl;
     871                        caseStmt->get_condition()->accept( *this );
     872                } // if
     873                output << ":\n";
    894874
    895875                std::list<Statement *> sts = caseStmt->get_statements();
     
    898878                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    899879                        output << indent << printLabels( (*i)->get_labels() )  ;
    900                         (*i)->accept( *visitor );
     880                        (*i)->accept( *this );
    901881                        output << endl;
    902882                } // for
     
    904884        }
    905885
    906         void CodeGenerator::postvisit( BranchStmt * branchStmt ) {
     886        void CodeGenerator::visit( BranchStmt * branchStmt ) {
    907887                switch ( branchStmt->get_type()) {
    908888                  case BranchStmt::Goto:
     
    912892                                if ( branchStmt->get_computedTarget() != 0 ) {
    913893                                        output << "goto *";
    914                                         branchStmt->get_computedTarget()->accept( *visitor );
     894                                        branchStmt->get_computedTarget()->accept( *this );
    915895                                } // if
    916896                        } // if
     
    926906        }
    927907
    928         void CodeGenerator::postvisit( ReturnStmt * returnStmt ) {
     908        void CodeGenerator::visit( ReturnStmt * returnStmt ) {
    929909                output << "return ";
    930                 maybeAccept( returnStmt->get_expr(), *visitor );
     910                maybeAccept( returnStmt->get_expr(), *this );
    931911                output << ";";
    932912        }
    933913
    934         void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
     914        void CodeGenerator::visit( ThrowStmt * throwStmt ) {
    935915                assertf( ! genC, "Throw statements should not reach code generation." );
    936916
     
    939919                if (throwStmt->get_expr()) {
    940920                        output << " ";
    941                         throwStmt->get_expr()->accept( *visitor );
     921                        throwStmt->get_expr()->accept( *this );
    942922                }
    943923                if (throwStmt->get_target()) {
    944924                        output << " _At ";
    945                         throwStmt->get_target()->accept( *visitor );
     925                        throwStmt->get_target()->accept( *this );
    946926                }
    947927                output << ";";
    948928        }
    949929
    950         void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
     930        void CodeGenerator::visit( WhileStmt * whileStmt ) {
    951931                if ( whileStmt->get_isDoWhile() ) {
    952932                        output << "do" ;
    953933                } else {
    954934                        output << "while (" ;
    955                         whileStmt->get_condition()->accept( *visitor );
     935                        whileStmt->get_condition()->accept( *this );
    956936                        output << ")";
    957937                } // if
     
    959939
    960940                output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
    961                 whileStmt->get_body()->accept( *visitor );
     941                whileStmt->get_body()->accept( *this );
    962942
    963943                output << indent;
     
    965945                if ( whileStmt->get_isDoWhile() ) {
    966946                        output << " while (" ;
    967                         whileStmt->get_condition()->accept( *visitor );
     947                        whileStmt->get_condition()->accept( *this );
    968948                        output << ");";
    969949                } // if
    970950        }
    971951
    972         void CodeGenerator::postvisit( ForStmt * forStmt ) {
     952        void CodeGenerator::visit( ForStmt * forStmt ) {
    973953                // initialization is always hoisted, so don't bother doing anything with that
    974954                output << "for (;";
    975955
    976956                if ( forStmt->get_condition() != 0 ) {
    977                         forStmt->get_condition()->accept( *visitor );
     957                        forStmt->get_condition()->accept( *this );
    978958                } // if
    979959                output << ";";
     
    982962                        // cast the top-level expression to void to reduce gcc warnings.
    983963                        Expression * expr = new CastExpr( forStmt->get_increment() );
    984                         expr->accept( *visitor );
     964                        expr->accept( *this );
    985965                } // if
    986966                output << ") ";
     
    988968                if ( forStmt->get_body() != 0 ) {
    989969                        output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
    990                         forStmt->get_body()->accept( *visitor );
    991                 } // if
    992         }
    993 
    994         void CodeGenerator::postvisit( __attribute__((unused)) NullStmt * nullStmt ) {
     970                        forStmt->get_body()->accept( *this );
     971                } // if
     972        }
     973
     974        void CodeGenerator::visit( __attribute__((unused)) NullStmt * nullStmt ) {
    995975                //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() );
    996976                output << "/* null statement */ ;";
    997977        }
    998978
    999         void CodeGenerator::postvisit( DeclStmt * declStmt ) {
    1000                 declStmt->get_decl()->accept( *visitor );
     979        void CodeGenerator::visit( DeclStmt * declStmt ) {
     980                declStmt->get_decl()->accept( *this );
    1001981
    1002982                if ( doSemicolon( declStmt->get_decl() ) ) {
    1003983                        output << ";";
    1004984                } // if
    1005         }
    1006 
    1007         void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1008                 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
    1009                 stmt->callStmt->accept( *visitor );
    1010985        }
    1011986
  • src/CodeGen/CodeGenerator.h

    r47b5b63 r39fea2f  
    2121
    2222#include "Common/Indenter.h"      // for Indenter
    23 #include "Common/PassVisitor.h"   // for PassVisitor
    2423#include "SynTree/Declaration.h"  // for DeclarationWithType (ptr only), Fun...
    2524#include "SynTree/Visitor.h"      // for Visitor
     
    2726
    2827namespace CodeGen {
    29         struct CodeGenerator : public WithShortCircuiting, public WithVisitorRef<CodeGenerator> {
    30           static int tabsize;
     28        class CodeGenerator : public Visitor {
     29          public:
     30                static int tabsize;
    3131
    3232                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false );
    33 
    34                 //*** Turn off visit_children for all nodes
    35                 void previsit( BaseSyntaxNode * );
    36 
    37                 //*** Error for unhandled node types
    38                 void postvisit( BaseSyntaxNode * );
     33                CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
     34                CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
    3935
    4036                //*** Declaration
    41                 void postvisit( StructDecl * );
    42                 void postvisit( FunctionDecl * );
    43                 void postvisit( ObjectDecl * );
    44                 void postvisit( UnionDecl *aggregateDecl );
    45                 void postvisit( EnumDecl *aggregateDecl );
    46                 void postvisit( TraitDecl *aggregateDecl );
    47                 void postvisit( TypedefDecl *typeDecl );
    48                 void postvisit( TypeDecl *typeDecl );
     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 );
    4945
    5046                //*** Initializer
    51                 void postvisit( Designation * );
    52                 void postvisit( SingleInit * );
    53                 void postvisit( ListInit * );
    54                 void postvisit( ConstructorInit * );
     47                virtual void visit( Designation * );
     48                virtual void visit( SingleInit * );
     49                virtual void visit( ListInit * );
     50                virtual void visit( ConstructorInit * );
    5551
    5652                //*** Constant
    57                 void postvisit( Constant * );
     53                virtual void visit( Constant * );
    5854
    5955                //*** Expression
    60                 void postvisit( ApplicationExpr *applicationExpr );
    61                 void postvisit( UntypedExpr *untypedExpr );
    62                 void postvisit( RangeExpr * rangeExpr );
    63                 void postvisit( NameExpr *nameExpr );
    64                 void postvisit( AddressExpr *addressExpr );
    65                 void postvisit( LabelAddressExpr *addressExpr );
    66                 void postvisit( CastExpr *castExpr );
    67                 void postvisit( VirtualCastExpr *castExpr );
    68                 void postvisit( UntypedMemberExpr *memberExpr );
    69                 void postvisit( MemberExpr *memberExpr );
    70                 void postvisit( VariableExpr *variableExpr );
    71                 void postvisit( ConstantExpr *constantExpr );
    72                 void postvisit( SizeofExpr *sizeofExpr );
    73                 void postvisit( AlignofExpr *alignofExpr );
    74                 void postvisit( UntypedOffsetofExpr *offsetofExpr );
    75                 void postvisit( OffsetofExpr *offsetofExpr );
    76                 void postvisit( OffsetPackExpr *offsetPackExpr );
    77                 void postvisit( LogicalExpr *logicalExpr );
    78                 void postvisit( ConditionalExpr *conditionalExpr );
    79                 void postvisit( CommaExpr *commaExpr );
    80                 void postvisit( CompoundLiteralExpr *compLitExpr );
    81                 void postvisit( UniqueExpr * );
    82                 void postvisit( TupleAssignExpr * tupleExpr );
    83                 void postvisit( UntypedTupleExpr *tupleExpr );
    84                 void postvisit( TupleExpr *tupleExpr );
    85                 void postvisit( TupleIndexExpr * tupleExpr );
    86                 void postvisit( TypeExpr *typeExpr );
    87                 void postvisit( AsmExpr * );
    88                 void postvisit( StmtExpr * );
    89                 void postvisit( ConstructorExpr * );
     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 * );
    9085
    9186                //*** Statements
    92                 void postvisit( CompoundStmt * );
    93                 void postvisit( ExprStmt * );
    94                 void postvisit( AsmStmt * );
    95                 void postvisit( AsmDecl * );                            // special: statement in declaration context
    96                 void postvisit( IfStmt * );
    97                 void postvisit( SwitchStmt * );
    98                 void postvisit( CaseStmt * );
    99                 void postvisit( BranchStmt * );
    100                 void postvisit( ReturnStmt * );
    101                 void postvisit( ThrowStmt * );
    102                 void postvisit( WhileStmt * );
    103                 void postvisit( ForStmt * );
    104                 void postvisit( NullStmt * );
    105                 void postvisit( DeclStmt * );
    106                 void postvisit( ImplicitCtorDtorStmt * );
     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 * );
    107101
    108102                void genAttributes( std::list< Attribute * > & attributes );
     
    123117
    124118                void updateLocation( BaseSyntaxNode const * to );
    125                 struct LineEnder {
    126                         CodeGenerator & cg;
    127                         LineEnder( CodeGenerator & cg ) : cg( cg ) {}
    128                         std::ostream & operator()(std::ostream &) const;
    129                 };
    130119          private:
    131120                Indenter indent;
    132                 std::ostream & output;
     121                bool insideFunction;
     122                std::ostream &output;
    133123                LabelPrinter printLabels;
    134124                bool pretty = false;  // pretty print
    135125                bool genC = false;    // true if output has to be C code
    136126                bool lineMarks = false;
    137         public:
    138                 LineEnder endl;
    139         private:
    140127
    141128                CodeLocation currentLocation;
    142129                void updateLocation( CodeLocation const & to );
     130                void nextLine();
    143131
    144132                void handleStorageClass( DeclarationWithType *decl );
     
    152140          if ( begin == end ) return;
    153141                for ( ;; ) {
    154                         (*begin++)->accept( *visitor );
     142                        (*begin++)->accept( *this );
    155143                  if ( begin == end ) break;
    156144                        output << ", ";                                                         // separator
     
    167155        /// returns C-compatible name of declaration
    168156        std::string genName( DeclarationWithType * decl );
    169 
    170         inline std::ostream & operator<<( std::ostream & os, const CodeGenerator::LineEnder & endl ) {
    171                 return endl( os );
    172         }
    173157} // namespace CodeGen
    174158
  • src/CodeGen/GenType.cc

    r47b5b63 r39fea2f  
    6363
    6464                if ( ! type->get_attributes().empty() ) {
    65                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    66                         cg.pass.genAttributes( type->get_attributes() );
     65                        CodeGenerator cg( os, pretty, genC, lineMarks );
     66                        cg.genAttributes( type->get_attributes() );
    6767                } // if
    6868
     
    116116                } // if
    117117                if ( dimension != 0 ) {
    118                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     118                        CodeGenerator cg( os, pretty, genC, lineMarks );
    119119                        dimension->accept( cg );
    120120                } else if ( isVarLen ) {
     
    178178                        } // if
    179179                } else {
    180                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     180                        CodeGenerator cg( os, pretty, genC, lineMarks );
    181181                        os << "(" ;
    182182
    183                         cg.pass.genCommaList( pars.begin(), pars.end() );
     183                        cg.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                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     203                        CodeGenerator cg( os, pretty, genC, lineMarks );
    204204                        os << "forall(";
    205                         cg.pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
     205                        cg.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                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     214                        CodeGenerator cg( os, pretty, genC, lineMarks );
    215215                        os << "(";
    216                         cg.pass.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
     216                        cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
    217217                        os << ") ";
    218218                        return os.str();
  • src/CodeGen/Generate.cc

    r47b5b63 r39fea2f  
    3333                /// Removes misc. nodes that should not exist in CodeGen
    3434                struct TreeCleaner {
    35                         void premutate( CompoundStmt * stmt );
    36                         Statement * postmutate( ImplicitCtorDtorStmt * stmt );
     35                        void previsit( CompoundStmt * stmt );
    3736
    3837                        static bool shouldClean( Declaration * );
     
    4241                        PassVisitor<TreeCleaner> cleaner;
    4342                        filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
    44                         mutateAll( translationUnit, cleaner );
     43                        acceptAll( translationUnit, cleaner );
    4544                } // cleanTree
    4645        } // namespace
     
    4948                cleanTree( translationUnit );
    5049
    51                 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks );
     50                CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
    5251                for ( auto & dcl : translationUnit ) {
    5352                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
    54                                 cgv.pass.updateLocation( dcl );
     53                                cgv.updateLocation( dcl );
    5554                                dcl->accept(cgv);
    5655                                if ( doSemicolon( dcl ) ) {
    5756                                        os << ";";
    5857                                } // if
    59                                 os << cgv.pass.endl;
     58                                os << std::endl;
    6059                        } // if
    6160                } // for
     
    6665                        os << CodeGen::genPrettyType( type, "" );
    6766                } else {
    68                         PassVisitor<CodeGenerator> cgv( os, true, false, false );
     67                        CodeGen::CodeGenerator cgv( os, true, false, false );
    6968                        node->accept( cgv );
    7069                }
     
    7372
    7473        namespace {
    75                 void TreeCleaner::premutate( CompoundStmt * cstmt ) {
     74                void TreeCleaner::previsit( CompoundStmt * cstmt ) {
    7675                        filter( cstmt->kids, [](Statement * stmt) {
    7776                                if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     
    8079                                return false;
    8180                        }, 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;
    8981                }
    9082
  • src/CodeTools/TrackLoc.cc

    r47b5b63 r39fea2f  
    3333
    3434namespace CodeTools {
     35
     36        std::ostream & operator<<(std::ostream & out, CodeLocation const & loc) {
     37                return out << loc.filename << '[' << loc.linenumber << ']';
     38        }
     39
    3540        class LocationPrinter {
    3641                size_t printLevel;
     
    6469                                }
    6570                                else {
    66                                         assertf( false, "Top level node has no CodeLocation %s", name.c_str() );
     71                                        std::cerr << "Top level node has no CodeLocation " << name << std::endl;
     72                                        exit(EXIT_FAILURE);
    6773                                }
    6874                        }
     
    8995                acceptAll( translationUnit, printer );
    9096        }
     97
    9198} // namespace CodeTools
    9299
  • src/Common/CodeLocation.h

    r47b5b63 r39fea2f  
    1616#pragma once
    1717
    18 #include <iostream>
    1918#include <string>
    2019
    2120struct CodeLocation {
    22         int first_line = -1, first_column = -1, last_line = -1, last_column = -1;
    23         std::string filename = "";
     21        int linenumber;
     22        std::string filename;
    2423
    2524        /// Create a new unset CodeLocation.
    26         CodeLocation() = default;
     25                CodeLocation()
     26                : linenumber( -1 )
     27                , filename("")
     28        {}
    2729
    2830        /// Create a new CodeLocation with the given values.
    2931        CodeLocation( const char* filename, int lineno )
    30                 : first_line( lineno )
     32                : linenumber( lineno )
    3133                , filename(filename ? filename : "")
    3234        {}
     
    3537
    3638        bool isSet () const {
    37                 return -1 != first_line;
     39                return -1 != linenumber;
    3840        }
    3941
     
    4244        }
    4345
     46        void unset () {
     47                linenumber = -1;
     48                filename = "";
     49        }
     50
     51        // Use field access for set.
     52
    4453        bool followedBy( CodeLocation const & other, int seperation ) {
    45                 return (first_line + seperation == other.first_line &&
     54                return (linenumber + seperation == other.linenumber &&
    4655                        filename == other.filename);
    4756        }
     
    5665};
    5766
    58 inline 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;
     67inline 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 " : "";
    6170}
     71
  • src/Common/PassVisitor.h

    r47b5b63 r39fea2f  
    133133        virtual void visit( OneType *oneType ) override final;
    134134
    135         virtual void visit( Designation *designation ) override final;
    136135        virtual void visit( SingleInit *singleInit ) override final;
    137136        virtual void visit( ListInit *listInit ) override final;
     
    222221        virtual Type* mutate( OneType *oneType ) override final;
    223222
    224         virtual Designation* mutate( Designation *designation ) override final;
    225223        virtual Initializer* mutate( SingleInit *singleInit ) override final;
    226224        virtual Initializer* mutate( ListInit *listInit ) override final;
  • src/Common/PassVisitor.impl.h

    r47b5b63 r39fea2f  
    19261926}
    19271927
    1928 template< typename pass_type >
    1929 void PassVisitor< pass_type >::visit( Designation * node ) {
    1930         VISIT_START( node );
    1931 
    1932         maybeAccept( node->get_designators(), *this );
    1933 
    1934         VISIT_END( node );
    1935 }
    1936 
    1937 template< typename pass_type >
    1938 Designation * 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 
    19461928//--------------------------------------------------------------------------
    19471929// SingleInit
  • src/Common/SemanticError.cc

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

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

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

    r47b5b63 r39fea2f  
    105105
    106106                /// collects constructed object decls - used as a base class
    107                 struct ObjDeclCollector : public WithGuards, public WithShortCircuiting {
     107                class ObjDeclCollector : public AddStmtVisitor {
     108                  public:
     109                        typedef AddStmtVisitor Parent;
     110                        using Parent::visit;
    108111                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
    109112                        typedef std::list< ObjectDecl * > ObjectSet;
    110                         void previsit( CompoundStmt *compoundStmt );
    111                         void previsit( DeclStmt *stmt );
     113                        virtual void visit( CompoundStmt *compoundStmt ) override;
     114                        virtual void visit( DeclStmt *stmt ) override;
    112115
    113116                        // don't go into other functions
    114                         void previsit( FunctionDecl * ) { visit_children = false; }
     117                        virtual void visit( FunctionDecl * ) override {}
    115118
    116119                  protected:
     
    136139                }
    137140
    138                 struct LabelFinder final : public ObjDeclCollector {
     141                class LabelFinder final : public ObjDeclCollector {
     142                  public:
     143                        typedef ObjDeclCollector Parent;
    139144                        typedef std::map< Label, ObjectSet > LabelMap;
    140145                        // map of Label -> live variables at that label
    141146                        LabelMap vars;
    142147
    143                         typedef ObjDeclCollector Parent;
    144                         using Parent::previsit;
    145                         void previsit( Statement * stmt );
    146 
    147                         void previsit( CompoundStmt *compoundStmt );
    148                         void previsit( DeclStmt *stmt );
     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 ); }
    149172                };
    150173
    151                 struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd {
     174                class InsertDtors final : public ObjDeclCollector {
     175                public:
    152176                        /// insert destructor calls at the appropriate places.  must happen before CtorInit nodes are removed
    153177                        /// (currently by FixInit)
    154178                        static void insert( std::list< Declaration * > & translationUnit );
    155179
     180                        typedef ObjDeclCollector Parent;
    156181                        typedef std::list< ObjectDecl * > OrderedDecls;
    157182                        typedef std::list< OrderedDecls > OrderedDeclsStack;
    158183
    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 );
     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;
    171194                private:
    172195                        void handleGoto( BranchStmt * stmt );
    173196
    174                         PassVisitor<LabelFinder> & finder;
     197                        LabelFinder & finder;
    175198                        LabelFinder::LabelMap & labelVars;
    176199                        OrderedDeclsStack reverseDeclOrder;
     
    310333
    311334                void InsertDtors::insert( std::list< Declaration * > & translationUnit ) {
    312                         PassVisitor<LabelFinder> finder;
    313                         PassVisitor<InsertDtors> inserter( finder );
     335                        LabelFinder finder;
     336                        InsertDtors inserter( finder );
    314337                        acceptAll( translationUnit, inserter );
    315338                }
     
    769792                }
    770793
    771                 void ObjDeclCollector::previsit( CompoundStmt * ) {
    772                         GuardValue( curVars );
    773                 }
    774 
    775                 void ObjDeclCollector::previsit( DeclStmt * stmt ) {
     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 ) {
    776801                        // keep track of all variables currently in scope
    777802                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    778803                                curVars.push_back( objDecl );
    779804                        } // if
    780                 }
    781 
    782                 void LabelFinder::previsit( Statement * stmt ) {
     805                        Parent::visit( stmt );
     806                }
     807
     808                void LabelFinder::handleStmt( Statement * stmt ) {
    783809                        // for each label, remember the variables in scope at that label.
    784810                        for ( Label l : stmt->get_labels() ) {
     
    786812                        } // for
    787813                }
    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 
    799814
    800815                template<typename Iterator, typename OutputIterator>
     
    812827                }
    813828
    814                 void InsertDtors::previsit( ObjectDecl * objDecl ) {
     829                void InsertDtors::visit( ObjectDecl * objDecl ) {
    815830                        // remember non-static destructed objects so that their destructors can be inserted later
    816831                        if ( ! objDecl->get_storageClasses().is_static ) {
     
    826841                                } // if
    827842                        } // if
    828                 }
    829 
    830                 void InsertDtors::previsit( FunctionDecl * funcDecl ) {
     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 ) {
    831853                        // each function needs to have its own set of labels
    832                         GuardValue( labelVars );
     854                        ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars );
    833855                        labelVars.clear();
    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 ) {
     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 ) {
    841864                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
    842865                        // when block is left, just the destructors associated with variables defined in this block, so push a new
    843866                        // list to the top of the stack so that we can differentiate scopes
    844867                        reverseDeclOrder.push_front( OrderedDecls() );
    845                         Parent::previsit( compoundStmt );
    846                 }
    847 
    848                 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
     868                        Parent::visit( compoundStmt );
     869
    849870                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
    850871                        // causes unreachable code warnings
     
    856877                }
    857878
    858                 void InsertDtors::previsit( ReturnStmt * ) {
     879                void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
    859880                        // return exits all scopes, so dump destructors for all scopes
    860881                        for ( OrderedDecls & od : reverseDeclOrder ) {
    861                                 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
     882                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );
    862883                        } // for
    863884                }
     
    907928                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    908929                                } // for
    909                                 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
     930                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
    910931                        } // if
    911932                }
    912933
    913                 void InsertDtors::previsit( BranchStmt * stmt ) {
     934                void InsertDtors::visit( BranchStmt * stmt ) {
    914935                        switch( stmt->get_type() ) {
    915936                          case BranchStmt::Continue:
  • src/Parser/ParseNode.h

    r47b5b63 r39fea2f  
    4444//##############################################################################
    4545
    46 typedef CodeLocation YYLTYPE;
    47 #define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
    48 
    4946extern char * yyfilename;
    5047extern int yylineno;
    51 extern YYLTYPE yylloc;
    5248
    5349class ParseNode {
     
    7773        ParseNode * next = nullptr;
    7874        std::string * name = nullptr;
    79         CodeLocation location = yylloc;
     75        CodeLocation location = { yyfilename, yylineno };
    8076}; // ParseNode
    8177
  • src/Parser/lex.ll

    r47b5b63 r39fea2f  
    2626
    2727unsigned int column = 0;                                                                // position of the end of the last token parsed
    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
     28#define YY_USER_ACTION column += yyleng;                                // trigger before each matching rule's action
    2929
    3030#include <string>
  • src/Parser/parser.yy

    r47b5b63 r39fea2f  
    116116
    117117bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
    118 
    119 # define YYLLOC_DEFAULT(Cur, Rhs, N)                            \
    120 do                                                              \
    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         }                                                             \
    134 while (0)
    135118%}
    136119
     
    363346%precedence ELSE        // token precedence for start of else clause in IF/WAITFOR statement
    364347
    365 %locations
    366348
    367349%start translation_unit                                                                 // parse-tree root
  • src/SymTab/Autogen.cc

    r47b5b63 r39fea2f  
    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

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

    r47b5b63 r39fea2f  
    1 dtor-early-exit.c:153:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:142: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

    r47b5b63 r39fea2f  
    1 dtor-early-exit.c:220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:142: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.