Changeset 74bba15


Ignore:
Timestamp:
Sep 26, 2017, 5:19:32 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
5dc26f5
Parents:
af58ee0 (diff), a7d151f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Location:
src
Files:
12 added
6 deleted
59 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    raf58ee0 r74bba15  
    443443        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    444444                extension( untypedExpr );
    445                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     445                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
    446446                        OperatorInfo opInfo;
    447                         if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
    448                                 std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
     447                        if ( operatorLookup( nameExpr->name, opInfo ) ) {
     448                                std::list< Expression* >::iterator arg = untypedExpr->args.begin();
    449449                                switch ( opInfo.type ) {
    450450                                  case OT_INDEX:
    451                                         assert( untypedExpr->get_args().size() == 2 );
     451                                        assert( untypedExpr->args.size() == 2 );
    452452                                        (*arg++)->accept( *visitor );
    453453                                        output << "[";
     
    461461                                  case OT_CTOR:
    462462                                  case OT_DTOR:
    463                                         if ( untypedExpr->get_args().size() == 1 ) {
     463                                        if ( untypedExpr->args.size() == 1 ) {
    464464                                                // the expression fed into a single parameter constructor or destructor may contain side
    465465                                                // effects, so must still output this expression
     
    480480                                                (*arg++)->accept( *visitor );
    481481                                                output << opInfo.symbol << "{ ";
    482                                                 genCommaList( arg, untypedExpr->get_args().end() );
     482                                                genCommaList( arg, untypedExpr->args.end() );
    483483                                                output << "}) /* " << opInfo.inputName << " */";
    484484                                        } // if
     
    488488                                  case OT_PREFIXASSIGN:
    489489                                  case OT_LABELADDRESS:
    490                                         assert( untypedExpr->get_args().size() == 1 );
     490                                        assert( untypedExpr->args.size() == 1 );
    491491                                        output << "(";
    492492                                        output << opInfo.symbol;
     
    497497                                  case OT_POSTFIX:
    498498                                  case OT_POSTFIXASSIGN:
    499                                         assert( untypedExpr->get_args().size() == 1 );
     499                                        assert( untypedExpr->args.size() == 1 );
    500500                                        (*arg)->accept( *visitor );
    501501                                        output << opInfo.symbol;
     
    504504                                  case OT_INFIX:
    505505                                  case OT_INFIXASSIGN:
    506                                         assert( untypedExpr->get_args().size() == 2 );
     506                                        assert( untypedExpr->args.size() == 2 );
    507507                                        output << "(";
    508508                                        (*arg++)->accept( *visitor );
     
    517517                                } // switch
    518518                        } else {
    519                                 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    520                                         assert( untypedExpr->get_args().size() == 2 );
    521                                         (*untypedExpr->get_args().begin())->accept( *visitor );
    522                                         output << " ... ";
    523                                         (*--untypedExpr->get_args().end())->accept( *visitor );
    524                                 } else {                                                                // builtin routines
    525                                         nameExpr->accept( *visitor );
    526                                         output << "(";
    527                                         genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    528                                         output << ")";
    529                                 } // if
     519                                // builtin routines
     520                                nameExpr->accept( *visitor );
     521                                output << "(";
     522                                genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
     523                                output << ")";
    530524                        } // if
    531525                } else {
    532                         untypedExpr->get_function()->accept( *visitor );
     526                        untypedExpr->function->accept( *visitor );
    533527                        output << "(";
    534                         genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     528                        genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
    535529                        output << ")";
    536530                } // if
     
    538532
    539533        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
    540                 rangeExpr->get_low()->accept( *visitor );
     534                rangeExpr->low->accept( *visitor );
    541535                output << " ... ";
    542                 rangeExpr->get_high()->accept( *visitor );
     536                rangeExpr->high->accept( *visitor );
    543537        }
    544538
     
    885879
    886880        void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
     881                updateLocation( caseStmt );
     882                output << indent;
    887883                if ( caseStmt->isDefault()) {
    888884                        output << "default";
     
    10261022} // namespace CodeGen
    10271023
     1024std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {
     1025        if ( node ) {
     1026                node->print( out );
     1027        } else {
     1028                out << "nullptr";
     1029        }
     1030        return out;
     1031}
     1032
    10281033// Local Variables: //
    10291034// tab-width: 4 //
  • src/Concurrency/Keywords.cc

    raf58ee0 r74bba15  
    528528                DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
    529529                auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
    530                 // if( type ) std::cerr << "FRED2" << std::endl;
    531530                if( type && type->get_baseStruct()->is_thread() ) {
    532531                        addStartStatement( decl, param );
  • src/Concurrency/Waitfor.cc

    raf58ee0 r74bba15  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "SymTab/AddVisit.h"       // for acceptAndAdd
     29#include "ResolvExpr/Resolver.h"   // for findVoidExpression
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithStmtsToAdd {
     114        class GenerateWaitForPass final : public WithIndexer {
    115115          public:
    116116
     
    126126
    127127                ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
     128                ObjectDecl * declareFlag( CompoundStmt * stmt );
     129                Statement  * makeSetter( ObjectDecl * flag );
    128130                ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt );
    129                 void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
    130                 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
    131                 Expression * call();
    132                 void choose();
     131                void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter, CompoundStmt * stmt );
     132                Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter, CompoundStmt * stmt );
     133                Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
     134                void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
    133135
    134136                static void implement( std::list< Declaration * > & translationUnit ) {
     
    140142          private:
    141143                FunctionDecl        * decl_waitfor    = nullptr;
     144                StructDecl          * decl_mask       = nullptr;
    142145                StructDecl          * decl_acceptable = nullptr;
    143146                StructDecl          * decl_monitor    = nullptr;
    144                 DeclarationWithType * decl_m_func     = nullptr;
    145                 DeclarationWithType * decl_m_count    = nullptr;
    146                 DeclarationWithType * decl_m_monitors = nullptr;
    147                 DeclarationWithType * decl_m_isdtor   = nullptr;
    148147
    149148                static std::unique_ptr< Type > generic_func;
    150149
     150                UniqueName namer_acc = "__acceptables_"s;
     151                UniqueName namer_idx = "__index_"s;
     152                UniqueName namer_flg = "__do_run_"s;
     153                UniqueName namer_msk = "__mask_"s;
    151154                UniqueName namer_mon = "__monitors_"s;
    152                 UniqueName namer_acc = "__acceptables_"s;
    153155                UniqueName namer_tim = "__timeout_"s;
    154156        };
     
    167169        namespace {
    168170                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    169                         return new ApplicationExpr(
     171                        return new UntypedExpr(
    170172                                new NameExpr( "?[?]" ),
    171173                                {
     
    177179
    178180                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    179                         return new ApplicationExpr(
     181                        return new UntypedExpr(
    180182                                        new NameExpr( "?=?" ),
    181183                                        { lhs, rhs }
     
    183185                }
    184186
    185                 Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) {
    186                         return new MemberExpr( mem, sue );
    187                 }
    188 
    189                 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) {
    190                         return new ExprStmt(
    191                                 noLabels,
    192                                 makeOpAssign(
    193                                         makeOpMember(
    194                                                 makeOpIndex(
    195                                                         object,
    196                                                         index
    197                                                 ),
    198                                                 member
     187                Expression * makeOpMember( Expression * sue, const std::string & mem ) {
     188                        return new UntypedMemberExpr( new NameExpr( mem ), sue );
     189                }
     190
     191                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
     192                        std::unique_ptr< Expression > expr( makeOpAssign(
     193                                makeOpMember(
     194                                        makeOpIndex(
     195                                                object,
     196                                                index
    199197                                        ),
    200                                         value
    201                                 )
    202                         );
     198                                        member
     199                                ),
     200                                value
     201                        ) );
     202
     203                        return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
    203204                }
    204205
     
    208209                        return new ConstantExpr( Constant::from_bool( ifnull ) );
    209210                }
     211
     212                VariableExpr * extractVariable( Expression * func ) {
     213                        if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {
     214                                return var;
     215                        }
     216
     217                        CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );
     218                        return strict_dynamic_cast< VariableExpr * >( cast->arg );
     219                }
     220
     221                Expression * detectIsDtor( Expression * func ) {
     222                        VariableExpr * typed_func = extractVariable( func );
     223                        bool is_dtor = InitTweak::isDestructor( typed_func->var );
     224                        return new ConstantExpr( Constant::from_bool( is_dtor ) );
     225                }
    210226        };
    211227
     
    216232
    217233        void GenerateWaitForPass::premutate( FunctionDecl * decl) {
    218                 if( decl->name != "__accept_internal" ) return;
     234                if( decl->name != "__waitfor_internal" ) return;
    219235
    220236                decl_waitfor = decl;
     
    227243                        assert( !decl_acceptable );
    228244                        decl_acceptable = decl;
    229                         for( Declaration * field : decl_acceptable->members ) {
    230                                      if( field->name == "func"    ) decl_m_func     = strict_dynamic_cast< DeclarationWithType * >( field );
    231                                 else if( field->name == "count"   ) decl_m_count    = strict_dynamic_cast< DeclarationWithType * >( field );
    232                                 else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field );
    233                                 else if( field->name == "is_dtor" ) decl_m_isdtor   = strict_dynamic_cast< DeclarationWithType * >( field );
    234                         }
    235 
     245                }
     246                else if( decl->name == "__waitfor_mask_t" ) {
     247                        assert( !decl_mask );
     248                        decl_mask = decl;
    236249                }
    237250                else if( decl->name == "monitor_desc" ) {
     
    242255
    243256        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    244                 return waitfor;
    245 
    246                 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
     257                if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    247258
    248259                CompoundStmt * stmt = new CompoundStmt( noLabels );
    249260
    250261                ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
     262                ObjectDecl * flag        = declareFlag( stmt );
     263                Statement  * setter      = makeSetter( flag );
    251264
    252265                int index = 0;
    253266                for( auto & clause : waitfor->clauses ) {
    254                         init( acceptables, index, clause, stmt );
     267                        init( acceptables, index, clause, setter, stmt );
    255268
    256269                        index++;
     
    262275                        waitfor->orelse .statement,
    263276                        waitfor->orelse .condition,
     277                        setter,
    264278                        stmt
    265279                );
    266280
    267                 // Expression * result  = call( acceptables, timeout, orelse, stmt );
    268 
    269                 // choose( waitfor, result );
     281                CompoundStmt * compound = new CompoundStmt( noLabels );
     282                stmt->push_back( new IfStmt(
     283                        noLabels,
     284                        safeCond( new VariableExpr( flag ) ),
     285                        compound,
     286                        nullptr
     287                ));
     288
     289                Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound );
     290
     291                choose( waitfor, result, compound );
    270292
    271293                return stmt;
     
    274296        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    275297        {
    276                 ObjectDecl * acceptables = new ObjectDecl(
     298                ObjectDecl * acceptables = ObjectDecl::newObject(
    277299                        namer_acc.newName(),
    278                         noStorage,
    279                         LinkageSpec::Cforall,
    280                         nullptr,
    281300                        new ArrayType(
    282301                                noQualifiers,
     
    294313                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    295314
     315                UntypedExpr * set = new UntypedExpr(
     316                        new NameExpr( "__builtin_memset" ),
     317                        {
     318                                new VariableExpr( acceptables ),
     319                                new ConstantExpr( Constant::from_int( 0 ) ),
     320                                new SizeofExpr( new VariableExpr( acceptables ) )
     321                        }
     322                );
     323
     324                Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );
     325                delete set;
     326
     327                stmt->push_back( new ExprStmt( noLabels, resolved_set ) );
     328
    296329                return acceptables;
    297330        }
    298331
     332        ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) {
     333                ObjectDecl * flag = ObjectDecl::newObject(
     334                        namer_flg.newName(),
     335                        new BasicType(
     336                                noQualifiers,
     337                                BasicType::Bool
     338                        ),
     339                        new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) )
     340                );
     341
     342                stmt->push_back( new DeclStmt( noLabels, flag) );
     343
     344                return flag;
     345        }
     346
     347        Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {
     348                Expression * untyped = new UntypedExpr(
     349                        new NameExpr( "?=?" ),
     350                        {
     351                                new VariableExpr( flag ),
     352                                new ConstantExpr( Constant::from_ulong( 1 ) )
     353                        }
     354                );
     355
     356                Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );
     357                delete untyped;
     358
     359                return new ExprStmt( noLabels, expr );
     360        }
     361
    299362        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    300363
    301                 ObjectDecl * mon = new ObjectDecl(
     364                ObjectDecl * mon = ObjectDecl::newObject(
    302365                        namer_mon.newName(),
    303                         noStorage,
    304                         LinkageSpec::Cforall,
    305                         nullptr,
    306366                        new ArrayType(
    307367                                noQualifiers,
    308                                 new StructInstType(
     368                                new PointerType(
    309369                                        noQualifiers,
    310                                         decl_monitor
     370                                        new StructInstType(
     371                                                noQualifiers,
     372                                                decl_monitor
     373                                        )
    311374                                ),
    312375                                new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ),
     
    316379                        new ListInit(
    317380                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
    318                                         return new SingleInit( expr );
     381                                        Expression * untyped = new CastExpr(
     382                                                new UntypedExpr(
     383                                                        new NameExpr( "get_monitor" ),
     384                                                        { expr }
     385                                                ),
     386                                                new PointerType(
     387                                                        noQualifiers,
     388                                                        new StructInstType(
     389                                                                noQualifiers,
     390                                                                decl_monitor
     391                                                        )
     392                                                )
     393                                        );
     394
     395                                        Expression * init = ResolvExpr::findSingleExpression( untyped, indexer );
     396                                        delete untyped;
     397                                        return new SingleInit( init );
    319398                                })
    320399                        )
     
    326405        }
    327406
    328         void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
     407        void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
    329408
    330409                ObjectDecl * monitors = declMon( clause, stmt );
    331410
    332                 CompoundStmt * compound = new CompoundStmt( noLabels );
    333                 compound->push_back( makeAccStatement( acceptables, index, decl_m_func    , clause.target.function ) );
    334                 compound->push_back( makeAccStatement( acceptables, index, decl_m_count   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) );
    335                 compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) );
    336                 compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor  , new ConstantExpr( Constant::from_bool( true ) ) ) );
     411                Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
    337412
    338413                stmt->push_back( new IfStmt(
    339414                        noLabels,
    340415                        safeCond( clause.condition ),
    341                         compound,
     416                        new CompoundStmt({
     417                                makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function )                                    , indexer ),
     418                                makeAccStatement( acceptables, index, "func"   , new CastExpr( clause.target.function, fptr_t )                            , indexer ),
     419                                makeAccStatement( acceptables, index, "list"   , new VariableExpr( monitors )                                              , indexer ),
     420                                makeAccStatement( acceptables, index, "size"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ),
     421                                setter->clone()
     422                        }),
    342423                        nullptr
    343424                ));
     
    353434                bool has_else,
    354435                Expression *& else_cond,
     436                Statement * setter,
    355437                CompoundStmt * stmt
    356438        ) {
    357                 ObjectDecl * timeout = new ObjectDecl(
     439                ObjectDecl * timeout = ObjectDecl::newObject(
    358440                        namer_tim.newName(),
    359                         noStorage,
    360                         LinkageSpec::Cforall,
    361                         nullptr,
    362441                        new BasicType(
    363442                                noQualifiers,
     
    374453                        stmt->push_back( new IfStmt(
    375454                                noLabels,
    376                                 safeCond( else_cond ),
    377                                 new ExprStmt(
    378                                         noLabels,
    379                                         makeOpAssign(
    380                                                 new VariableExpr( timeout ),
    381                                                 time
    382                                         )
    383                                 ),
     455                                safeCond( time_cond ),
     456                                new CompoundStmt({
     457                                        new ExprStmt(
     458                                                noLabels,
     459                                                makeOpAssign(
     460                                                        new VariableExpr( timeout ),
     461                                                        time
     462                                                )
     463                                        ),
     464                                        setter->clone()
     465                                }),
    384466                                nullptr
    385467                        ));
     
    392474                                noLabels,
    393475                                safeCond( else_cond ),
    394                                 new ExprStmt(
    395                                         noLabels,
    396                                         makeOpAssign(
    397                                                 new VariableExpr( timeout ),
    398                                                 new ConstantExpr( Constant::from_ulong( 0 ) )
    399                                         )
    400                                 ),
     476                                new CompoundStmt({
     477                                        new ExprStmt(
     478                                                noLabels,
     479                                                makeOpAssign(
     480                                                        new VariableExpr( timeout ),
     481                                                        new ConstantExpr( Constant::from_ulong( 0 ) )
     482                                                )
     483                                        ),
     484                                        setter->clone()
     485                                }),
    401486                                nullptr
    402487                        ));
     
    405490                }
    406491
     492                delete setter;
     493
    407494                return new VariableExpr( timeout );
     495        }
     496
     497        Expression * GenerateWaitForPass::call(
     498                size_t count,
     499                ObjectDecl * acceptables,
     500                Expression * timeout,
     501                CompoundStmt * stmt
     502        ) {
     503                ObjectDecl * index = ObjectDecl::newObject(
     504                        namer_idx.newName(),
     505                        new BasicType(
     506                                noQualifiers,
     507                                BasicType::ShortSignedInt
     508                        ),
     509                        new SingleInit(
     510                                new ConstantExpr( Constant::from_int( -1 ) )
     511                        )
     512                );
     513
     514                stmt->push_back( new DeclStmt( noLabels, index ) );
     515
     516                ObjectDecl * mask = ObjectDecl::newObject(
     517                        namer_msk.newName(),
     518                        new StructInstType(
     519                                noQualifiers,
     520                                decl_mask
     521                        ),
     522                        new ListInit({
     523                                new SingleInit( new AddressExpr( new VariableExpr( index ) ) ),
     524                                new SingleInit( new VariableExpr( acceptables ) ),
     525                                new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) )
     526                        })
     527                );
     528
     529                stmt->push_back( new DeclStmt( noLabels, mask ) );
     530
     531                stmt->push_back( new ExprStmt(
     532                        noLabels,
     533                        new ApplicationExpr(
     534                                VariableExpr::functionPointer( decl_waitfor ),
     535                                {
     536                                        new CastExpr(
     537                                                new VariableExpr( mask ),
     538                                                new ReferenceType(
     539                                                        noQualifiers,
     540                                                        new StructInstType(
     541                                                                noQualifiers,
     542                                                                decl_mask
     543                                                        )
     544                                                )
     545                                        ),
     546                                        timeout
     547                                }
     548                        )
     549                ));
     550
     551                return new VariableExpr( index );
     552        }
     553
     554        void GenerateWaitForPass::choose(
     555                WaitForStmt * waitfor,
     556                Expression  * result,
     557                CompoundStmt * stmt
     558        ) {
     559                SwitchStmt * swtch = new SwitchStmt(
     560                        noLabels,
     561                        result,
     562                        std::list<Statement *>()
     563                );
     564
     565                unsigned long i = 0;
     566                for( auto & clause : waitfor->clauses ) {
     567                        swtch->statements.push_back(
     568                                new CaseStmt(
     569                                        noLabels,
     570                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
     571                                        {
     572                                                clause.statement,
     573                                                new BranchStmt(
     574                                                        noLabels,
     575                                                        "",
     576                                                        BranchStmt::Break
     577                                                )
     578                                        }
     579                                )
     580                        );
     581                }
     582
     583                if(waitfor->timeout.statement) {
     584                        swtch->statements.push_back(
     585                                new CaseStmt(
     586                                        noLabels,
     587                                        new ConstantExpr( Constant::from_int( -2 ) ),
     588                                        {
     589                                                waitfor->timeout.statement,
     590                                                new BranchStmt(
     591                                                        noLabels,
     592                                                        "",
     593                                                        BranchStmt::Break
     594                                                )
     595                                        }
     596                                )
     597                        );
     598                }
     599
     600                if(waitfor->orelse.statement) {
     601                        swtch->statements.push_back(
     602                                new CaseStmt(
     603                                        noLabels,
     604                                        new ConstantExpr( Constant::from_int( -1 ) ),
     605                                        {
     606                                                waitfor->orelse.statement,
     607                                                new BranchStmt(
     608                                                        noLabels,
     609                                                        "",
     610                                                        BranchStmt::Break
     611                                                )
     612                                        }
     613                                )
     614                        );
     615                }
     616
     617                stmt->push_back( swtch );
    408618        }
    409619};
  • src/GenPoly/Box.cc

    raf58ee0 r74bba15  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
    34 #include "DeclMutator.h"                 // for DeclMutator
    3534#include "FindFunction.h"                // for findFunction, findAndReplace...
    3635#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3938#include "Lvalue.h"                      // for generalizedLvalue
    4039#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
    41 #include "PolyMutator.h"                 // for PolyMutator
    4240#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4341#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6260                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6361
     62                class BoxPass {
     63                protected:
     64                        BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
     65                        TyVarMap scopeTyVars;
     66                };
     67
    6468                /// Adds layout-generation functions to polymorphic types
    65                 class LayoutFunctionBuilder final : public DeclMutator {
    66                         unsigned int functionNesting;  // current level of nested functions
     69                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
     70                        unsigned int functionNesting = 0;  // current level of nested functions
    6771                public:
    68                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    69 
    70                         using DeclMutator::mutate;
    71                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    72                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    73                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
     72                        void previsit( FunctionDecl *functionDecl );
     73                        void previsit( StructDecl *structDecl );
     74                        void previsit( UnionDecl *unionDecl );
    7475                };
    7576
    7677                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    77                 class Pass1 final : public PolyMutator {
     78                class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7879                  public:
    7980                        Pass1();
    8081
    81                         using PolyMutator::mutate;
    82                         virtual Expression *mutate( ApplicationExpr *appExpr ) override;
    83                         virtual Expression *mutate( AddressExpr *addrExpr ) override;
    84                         virtual Expression *mutate( UntypedExpr *expr ) override;
    85                         virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override;
    86                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    87                         virtual Expression *mutate( CommaExpr *commaExpr ) override;
    88                         virtual Expression *mutate( ConditionalExpr *condExpr ) override;
    89                         virtual Statement * mutate( ReturnStmt *returnStmt ) override;
    90                         virtual Type *mutate( PointerType *pointerType ) override;
    91                         virtual Type * mutate( FunctionType *functionType ) override;
    92 
    93                         virtual void doBeginScope() override;
    94                         virtual void doEndScope() override;
     82                        void premutate( FunctionDecl * functionDecl );
     83                        void premutate( TypeDecl * typeDecl );
     84                        void premutate( CommaExpr * commaExpr );
     85                        Expression * postmutate( ApplicationExpr * appExpr );
     86                        Expression * postmutate( UntypedExpr *expr );
     87                        void premutate( AddressExpr * addrExpr );
     88                        Expression * postmutate( AddressExpr * addrExpr );
     89                        void premutate( ReturnStmt * returnStmt );
     90                        void premutate( PointerType * pointerType );
     91                        void premutate( FunctionType * functionType );
     92
     93                        void beginScope();
     94                        void endScope();
    9595                  private:
    9696                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
     
    129129                /// * Moves polymorphic returns in function types to pointer-type parameters
    130130                /// * adds type size and assertion parameters to parameter lists
    131                 class Pass2 final : public PolyMutator {
    132                   public:
    133                         template< typename DeclClass >
    134                         DeclClass *handleDecl( DeclClass *decl );
    135                         template< typename AggDecl >
    136                         AggDecl * handleAggDecl( AggDecl * aggDecl );
    137 
    138                         typedef PolyMutator Parent;
    139                         using Parent::mutate;
    140                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    141                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    142                         virtual StructDecl *mutate( StructDecl *structDecl ) override;
    143                         virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
    144                         virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
    145                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    146                         virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
    147                         virtual Type *mutate( PointerType *pointerType ) override;
    148                         virtual Type *mutate( FunctionType *funcType ) override;
     131                struct Pass2 final : public BoxPass, public WithGuards {
     132                        void handleAggDecl();
     133
     134                        DeclarationWithType * postmutate( FunctionDecl *functionDecl );
     135                        void premutate( StructDecl *structDecl );
     136                        void premutate( UnionDecl *unionDecl );
     137                        void premutate( TraitDecl *unionDecl );
     138                        void premutate( TypeDecl *typeDecl );
     139                        void premutate( PointerType *pointerType );
     140                        void premutate( FunctionType *funcType );
    149141
    150142                  private:
     
    158150                /// * Calculates polymorphic offsetof expressions from offset array
    159151                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    160                 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     152                class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    161153                public:
    162154                        PolyGenericCalculator();
     
    197189                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    198190                        UniqueName bufNamer;                           ///< Namer for VLA buffers
    199                         TyVarMap scopeTyVars;
    200191                };
    201192
    202193                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
    203                 class Pass3 final : public PolyMutator {
    204                   public:
     194                struct Pass3 final : public BoxPass, public WithGuards {
    205195                        template< typename DeclClass >
    206                         DeclClass *handleDecl( DeclClass *decl, Type *type );
    207 
    208                         using PolyMutator::mutate;
    209                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    210                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    211                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
    212                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    213                         virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
    214                         virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
    215                         virtual Type *mutate( PointerType *pointerType ) override;
    216                         virtual Type *mutate( FunctionType *funcType ) override;
    217                   private:
     196                        void handleDecl( DeclClass * decl, Type * type );
     197
     198                        void premutate( ObjectDecl * objectDecl );
     199                        void premutate( FunctionDecl * functionDecl );
     200                        void premutate( TypedefDecl * typedefDecl );
     201                        void premutate( StructDecl * structDecl );
     202                        void premutate( UnionDecl * unionDecl );
     203                        void premutate( TypeDecl * typeDecl );
     204                        void premutate( PointerType * pointerType );
     205                        void premutate( FunctionType * funcType );
    218206                };
    219207        } // anonymous namespace
     
    247235
    248236        void box( std::list< Declaration *>& translationUnit ) {
    249                 LayoutFunctionBuilder layoutBuilder;
    250                 Pass1 pass1;
    251                 Pass2 pass2;
     237                PassVisitor<LayoutFunctionBuilder> layoutBuilder;
     238                PassVisitor<Pass1> pass1;
     239                PassVisitor<Pass2> pass2;
    252240                PassVisitor<PolyGenericCalculator> polyCalculator;
    253                 Pass3 pass3;
    254 
    255                 layoutBuilder.mutateDeclarationList( translationUnit );
    256                 mutateTranslationUnit/*All*/( translationUnit, pass1 );
    257                 mutateTranslationUnit/*All*/( translationUnit, pass2 );
     241                PassVisitor<Pass3> pass3;
     242
     243                acceptAll( translationUnit, layoutBuilder );
     244                mutateAll( translationUnit, pass1 );
     245                mutateAll( translationUnit, pass2 );
    258246                mutateAll( translationUnit, polyCalculator );
    259                 mutateTranslationUnit/*All*/( translationUnit, pass3 );
     247                mutateAll( translationUnit, pass3 );
    260248        }
    261249
    262250        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    263251
    264         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    265                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     252        void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
     253                visit_children = false;
     254                maybeAccept( functionDecl->get_functionType(), *visitor );
    266255                ++functionNesting;
    267                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     256                maybeAccept( functionDecl->get_statements(), *visitor );
    268257                --functionNesting;
    269                 return functionDecl;
    270258        }
    271259
     
    356344        }
    357345
    358         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
     346        void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
    359347                // do not generate layout function for "empty" tag structs
    360                 if ( structDecl->get_members().empty() ) return structDecl;
     348                visit_children = false;
     349                if ( structDecl->get_members().empty() ) return;
    361350
    362351                // get parameters that can change layout, exiting early if none
    363352                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    364                 if ( otypeParams.empty() ) return structDecl;
     353                if ( otypeParams.empty() ) return;
    365354
    366355                // build layout function signature
     
    413402                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    414403
    415                 addDeclarationAfter( layoutDecl );
    416                 return structDecl;
     404                declsToAddAfter.push_back( layoutDecl );
    417405        }
    418406
    419         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
     407        void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
    420408                // do not generate layout function for "empty" tag unions
    421                 if ( unionDecl->get_members().empty() ) return unionDecl;
     409                visit_children = false;
     410                if ( unionDecl->get_members().empty() ) return;
    422411
    423412                // get parameters that can change layout, exiting early if none
    424413                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    425                 if ( otypeParams.empty() ) return unionDecl;
     414                if ( otypeParams.empty() ) return;
    426415
    427416                // build layout function signature
     
    456445                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    457446
    458                 addDeclarationAfter( layoutDecl );
    459                 return unionDecl;
     447                declsToAddAfter.push_back( layoutDecl );
    460448        }
    461449
     
    501489                Pass1::Pass1() : tempNamer( "_temp" ) {}
    502490
    503                 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     491                void Pass1::premutate( FunctionDecl *functionDecl ) {
    504492                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    505493                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506                                 doBeginScope();
    507                                 scopeTyVars.beginScope();
    508 
    509                                 DeclarationWithType *oldRetval = retval;
     494                                GuardScope( scopeTyVars );
     495                                GuardValue( retval );
    510496
    511497                                // process polymorphic return value
    512498                                retval = nullptr;
    513                                 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
    514                                         retval = functionDecl->get_functionType()->get_returnVals().front();
     499                                FunctionType *functionType = functionDecl->type;
     500                                if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
     501                                        retval = functionType->returnVals.front();
    515502
    516503                                        // give names to unnamed return values
    517                                         if ( retval->get_name() == "" ) {
    518                                                 retval->set_name( "_retparm" );
    519                                                 retval->set_linkage( LinkageSpec::C );
     504                                        if ( retval->name == "" ) {
     505                                                retval->name = "_retparm";
     506                                                retval->linkage = LinkageSpec::C;
    520507                                        } // if
    521508                                } // if
    522509
    523                                 FunctionType *functionType = functionDecl->get_functionType();
    524                                 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    525 
    526                                 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     510                                makeTyVarMap( functionType, scopeTyVars );
     511
     512                                std::list< DeclarationWithType *> &paramList = functionType->parameters;
    527513                                std::list< FunctionType *> functions;
    528                                 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    529                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     514                                for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {
     515                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    530516                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    531517                                        } // for
     
    542528                                        } // if
    543529                                } // for
    544 
    545                                 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    546 
    547                                 scopeTyVars.endScope();
    548                                 retval = oldRetval;
    549                                 doEndScope();
    550530                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    551531                        } // if
    552                         return functionDecl;
    553                 }
    554 
    555                 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
     532                }
     533
     534                void Pass1::premutate( TypeDecl *typeDecl ) {
    556535                        addToTyVarMap( typeDecl, scopeTyVars );
    557                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    558                 }
    559 
    560                 Expression *Pass1::mutate( CommaExpr *commaExpr ) {
     536                }
     537
     538                void Pass1::premutate( CommaExpr *commaExpr ) {
    561539                        // Attempting to find application expressions that were mutated by the copy constructor passes
    562540                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    574552                                }
    575553                        }
    576 
    577                         commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    578                         commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
    579                         return commaExpr;
    580                 }
    581 
    582                 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
    583                         condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
    584                         condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
    585                         condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
    586                         return condExpr;
    587 
    588554                }
    589555
     
    659625                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    660626                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    661                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     627                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    662628                        return newObj;
    663629                }
     
    775741                                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    776742                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    777                                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     743                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    778744                                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    779745                                        assign->get_args().push_back( new VariableExpr( newObj ) );
    780746                                        assign->get_args().push_back( arg );
    781                                         stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
     747                                        stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
    782748                                        arg = new AddressExpr( new VariableExpr( newObj ) );
    783749                                } // if
     
    961927                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    962928                                                adapter = answer.first;
    963                                                 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     929                                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
    964930                                        } // if
    965931                                        assert( adapter != adapters.end() );
     
    11181084                }
    11191085
    1120                 Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
     1086                Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
    11211087                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11221088                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    11241090                        // }
    11251091                        // std::cerr << "\n";
    1126                         appExpr->get_function()->acceptMutator( *this );
    1127                         mutateAll( appExpr->get_args(), *this );
    1128 
    1129                         assert( appExpr->get_function()->has_result() );
    1130                         FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
    1131                         assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
     1092
     1093                        assert( appExpr->function->result );
     1094                        FunctionType * function = getFunctionType( appExpr->function->result );
     1095                        assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
    11321096
    11331097                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11821146                }
    11831147
    1184                 Expression *Pass1::mutate( UntypedExpr *expr ) {
    1185                         if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    1186                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     1148                Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1149                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
     1150                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11871151                                        if ( name->get_name() == "*?" ) {
    1188                                                 Expression *ret = expr->get_args().front();
    1189                                                 expr->get_args().clear();
     1152                                                Expression *ret = expr->args.front();
     1153                                                expr->args.clear();
    11901154                                                delete expr;
    1191                                                 return ret->acceptMutator( *this );
     1155                                                return ret;
    11921156                                        } // if
    11931157                                } // if
    11941158                        } // if
    1195                         return PolyMutator::mutate( expr );
    1196                 }
    1197 
    1198                 Expression *Pass1::mutate( AddressExpr *addrExpr ) {
     1159                        return expr;
     1160                }
     1161
     1162                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
     1163                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
    11991164                        assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
    12001165
     
    12161181                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    12171182                        // out of the if condition.
    1218                         addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
     1183                        addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
    12191184                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    12201185                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    12311196                }
    12321197
    1233                 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    1234                         if ( retval && returnStmt->get_expr() ) {
    1235                                 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
    1236                                 delete returnStmt->get_expr();
    1237                                 returnStmt->set_expr( 0 );
    1238                         } else {
    1239                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     1198                void Pass1::premutate( ReturnStmt *returnStmt ) {
     1199                        if ( retval && returnStmt->expr ) {
     1200                                assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() );
     1201                                delete returnStmt->expr;
     1202                                returnStmt->expr = nullptr;
    12401203                        } // if
    1241                         return returnStmt;
    1242                 }
    1243 
    1244                 Type * Pass1::mutate( PointerType *pointerType ) {
    1245                         scopeTyVars.beginScope();
     1204                }
     1205
     1206                void Pass1::premutate( PointerType *pointerType ) {
     1207                        GuardScope( scopeTyVars );
    12461208                        makeTyVarMap( pointerType, scopeTyVars );
    1247 
    1248                         Type *ret = Mutator::mutate( pointerType );
    1249 
    1250                         scopeTyVars.endScope();
    1251                         return ret;
    1252                 }
    1253 
    1254                 Type * Pass1::mutate( FunctionType *functionType ) {
    1255                         scopeTyVars.beginScope();
     1209                }
     1210
     1211                void Pass1::premutate( FunctionType *functionType ) {
     1212                        GuardScope( scopeTyVars );
    12561213                        makeTyVarMap( functionType, scopeTyVars );
    1257 
    1258                         Type *ret = Mutator::mutate( functionType );
    1259 
    1260                         scopeTyVars.endScope();
    1261                         return ret;
    1262                 }
    1263 
    1264                 void Pass1::doBeginScope() {
     1214                }
     1215
     1216                void Pass1::beginScope() {
    12651217                        adapters.beginScope();
    12661218                }
    12671219
    1268                 void Pass1::doEndScope() {
     1220                void Pass1::endScope() {
    12691221                        adapters.endScope();
    12701222                }
     
    12931245                }
    12941246
    1295                 template< typename DeclClass >
    1296                 DeclClass * Pass2::handleDecl( DeclClass *decl ) {
    1297                         DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
    1298 
    1299                         return ret;
    1300                 }
    1301 
    1302                 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
    1303                         functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
     1247                DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
    13041248                        FunctionType * ftype = functionDecl->get_functionType();
    13051249                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    13251269                }
    13261270
    1327                 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
    1328                         return handleDecl( objectDecl );
    1329                 }
    1330 
    1331                 template< typename AggDecl >
    1332                 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
     1271                void Pass2::premutate( StructDecl * ) {
    13331272                        // prevent tyVars from leaking into containing scope
    1334                         scopeTyVars.beginScope();
    1335                         Parent::mutate( aggDecl );
    1336                         scopeTyVars.endScope();
    1337                         return aggDecl;
    1338                 }
    1339 
    1340                 StructDecl * Pass2::mutate( StructDecl *aggDecl ) {
    1341                         return handleAggDecl( aggDecl );
    1342                 }
    1343 
    1344                 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) {
    1345                         return handleAggDecl( aggDecl );
    1346                 }
    1347 
    1348                 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
    1349                         return handleAggDecl( aggDecl );
    1350                 }
    1351 
    1352                 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
     1273                        GuardScope( scopeTyVars );
     1274                }
     1275
     1276                void Pass2::premutate( UnionDecl * ) {
     1277                        // prevent tyVars from leaking into containing scope
     1278                        GuardScope( scopeTyVars );
     1279                }
     1280
     1281                void Pass2::premutate( TraitDecl * ) {
     1282                        // prevent tyVars from leaking into containing scope
     1283                        GuardScope( scopeTyVars );
     1284                }
     1285
     1286                void Pass2::premutate( TypeDecl *typeDecl ) {
    13531287                        addToTyVarMap( typeDecl, scopeTyVars );
    1354                         if ( typeDecl->get_base() ) {
    1355                                 return handleDecl( typeDecl );
    1356                         } else {
    1357                                 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
    1358                         }
    1359                 }
    1360 
    1361                 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
    1362                         return handleDecl( typedefDecl );
    1363                 }
    1364 
    1365                 Type * Pass2::mutate( PointerType *pointerType ) {
    1366                         scopeTyVars.beginScope();
     1288                }
     1289
     1290                void Pass2::premutate( PointerType *pointerType ) {
     1291                        GuardScope( scopeTyVars );
    13671292                        makeTyVarMap( pointerType, scopeTyVars );
    1368 
    1369                         Type *ret = Parent::mutate( pointerType );
    1370 
    1371                         scopeTyVars.endScope();
    1372                         return ret;
    1373                 }
    1374 
    1375                 Type *Pass2::mutate( FunctionType *funcType ) {
    1376                         scopeTyVars.beginScope();
    1377 
     1293                }
     1294
     1295                void Pass2::premutate( FunctionType *funcType ) {
     1296                        GuardScope( scopeTyVars );
    13781297                        makeTyVarMap( funcType, scopeTyVars );
    13791298
     
    14141333                                // move all assertions into parameter list
    14151334                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1416 //      *assert = (*assert)->acceptMutator( *this );
    14171335                                        // assertion parameters may not be used in body, pass along with unused attribute.
    14181336                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    14501368                                                }
    14511369                                        }
    1452 
    14531370                                        seenTypes.insert( typeName );
    14541371                                }
     
    14581375                        funcType->get_parameters().splice( last, inferredParams );
    14591376                        addAdapters( funcType );
    1460                         mutateAll( funcType->get_returnVals(), *this );
    1461                         mutateAll( funcType->get_parameters(), *this );
    1462 
    1463                         scopeTyVars.endScope();
    1464                         return funcType;
    14651377                }
    14661378
     
    14681380
    14691381                PolyGenericCalculator::PolyGenericCalculator()
    1470                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
     1382                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
    14711383
    14721384                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    18291741
    18301742                template< typename DeclClass >
    1831                 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
    1832                         scopeTyVars.beginScope();
     1743                void Pass3::handleDecl( DeclClass * decl, Type * type ) {
     1744                        GuardScope( scopeTyVars );
    18331745                        makeTyVarMap( type, scopeTyVars );
    1834 
    1835                         DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    1836                         // ScrubTyVars::scrub( decl, scopeTyVars );
    18371746                        ScrubTyVars::scrubAll( decl );
    1838 
    1839                         scopeTyVars.endScope();
    1840                         return ret;
    1841                 }
    1842 
    1843                 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
    1844                         return handleDecl( objectDecl, objectDecl->get_type() );
    1845                 }
    1846 
    1847                 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
    1848                         return handleDecl( functionDecl, functionDecl->get_functionType() );
    1849                 }
    1850 
    1851                 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
    1852                         return handleDecl( typedefDecl, typedefDecl->get_base() );
     1747                }
     1748
     1749                void Pass3::premutate( ObjectDecl * objectDecl ) {
     1750                        handleDecl( objectDecl, objectDecl->type );
     1751                }
     1752
     1753                void Pass3::premutate( FunctionDecl * functionDecl ) {
     1754                        handleDecl( functionDecl, functionDecl->type );
     1755                }
     1756
     1757                void Pass3::premutate( TypedefDecl * typedefDecl ) {
     1758                        handleDecl( typedefDecl, typedefDecl->base );
    18531759                }
    18541760
    18551761                /// Strips the members from a generic aggregate
    1856                 void stripGenericMembers(AggregateDecl* decl) {
    1857                         if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
    1858                 }
    1859 
    1860                 Declaration *Pass3::mutate( StructDecl *structDecl ) {
     1762                void stripGenericMembers(AggregateDecl * decl) {
     1763                        if ( ! decl->parameters.empty() ) decl->members.clear();
     1764                }
     1765
     1766                void Pass3::premutate( StructDecl * structDecl ) {
    18611767                        stripGenericMembers( structDecl );
    1862                         return structDecl;
    1863                 }
    1864 
    1865                 Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
     1768                }
     1769
     1770                void Pass3::premutate( UnionDecl * unionDecl ) {
    18661771                        stripGenericMembers( unionDecl );
    1867                         return unionDecl;
    1868                 }
    1869 
    1870                 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1871 //   Initializer *init = 0;
    1872 //   std::list< Expression *> designators;
    1873 //   addToTyVarMap( typeDecl, scopeTyVars );
    1874 //   if ( typeDecl->get_base() ) {
    1875 //     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1876 //   }
    1877 //   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    1878 
     1772                }
     1773
     1774                void Pass3::premutate( TypeDecl * typeDecl ) {
    18791775                        addToTyVarMap( typeDecl, scopeTyVars );
    1880                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    1881                 }
    1882 
    1883                 Type * Pass3::mutate( PointerType *pointerType ) {
    1884                         scopeTyVars.beginScope();
     1776                }
     1777
     1778                void Pass3::premutate( PointerType * pointerType ) {
     1779                        GuardScope( scopeTyVars );
    18851780                        makeTyVarMap( pointerType, scopeTyVars );
    1886 
    1887                         Type *ret = Mutator::mutate( pointerType );
    1888 
    1889                         scopeTyVars.endScope();
    1890                         return ret;
    1891                 }
    1892 
    1893                 Type * Pass3::mutate( FunctionType *functionType ) {
    1894                         scopeTyVars.beginScope();
     1781                }
     1782
     1783                void Pass3::premutate( FunctionType * functionType ) {
     1784                        GuardScope( scopeTyVars );
    18951785                        makeTyVarMap( functionType, scopeTyVars );
    1896 
    1897                         Type *ret = Mutator::mutate( functionType );
    1898 
    1899                         scopeTyVars.endScope();
    1900                         return ret;
    19011786                }
    19021787        } // anonymous namespace
  • src/GenPoly/Specialize.cc

    raf58ee0 r74bba15  
    2222#include <utility>                       // for pair
    2323
     24#include "Common/PassVisitor.h"
    2425#include "Common/SemanticError.h"        // for SemanticError
    2526#include "Common/UniqueName.h"           // for UniqueName
     
    2829#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    2930#include "Parser/LinkageSpec.h"          // for C
    30 #include "PolyMutator.h"                 // for PolyMutator
    3131#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    3232#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    4343
    4444namespace GenPoly {
    45         class Specialize final : public PolyMutator {
    46           public:
    47                 using PolyMutator::mutate;
    48                 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override;
    49                 virtual Expression * mutate( AddressExpr *castExpr ) override;
    50                 virtual Expression * mutate( CastExpr *castExpr ) override;
    51                 // virtual Expression * mutate( LogicalExpr *logicalExpr );
    52                 // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
    53                 // virtual Expression * mutate( CommaExpr *commaExpr );
     45        struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
     46                Expression * postmutate( ApplicationExpr *applicationExpr );
     47                Expression * postmutate( AddressExpr *castExpr );
     48                Expression * postmutate( CastExpr *castExpr );
    5449
    5550                void handleExplicitParams( ApplicationExpr *appExpr );
     
    204199        }
    205200
    206         struct EnvTrimmer : public Visitor {
     201        struct EnvTrimmer {
    207202                TypeSubstitution * env, * newEnv;
    208203                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    209                 virtual void visit( TypeDecl * tyDecl ) {
     204                void previsit( TypeDecl * tyDecl ) {
    210205                        // transfer known bindings for seen type variables
    211                         if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
    212                                 newEnv->add( tyDecl->get_name(), t );
     206                        if ( Type * t = env->lookup( tyDecl->name ) ) {
     207                                newEnv->add( tyDecl->name, t );
    213208                        }
    214209                }
     
    219214                if ( env ) {
    220215                        TypeSubstitution * newEnv = new TypeSubstitution();
    221                         EnvTrimmer trimmer( env, newEnv );
     216                        PassVisitor<EnvTrimmer> trimmer( env, newEnv );
    222217                        expr->accept( trimmer );
    223218                        return newEnv;
     
    277272                std::string oldParamPrefix = paramPrefix;
    278273                paramPrefix += "p";
    279                 // save stmtsToAdd in oldStmts
     274                // save stmtsToAddBefore in oldStmts
    280275                std::list< Statement* > oldStmts;
    281                 oldStmts.splice( oldStmts.end(), stmtsToAdd );
    282                 mutate( appExpr );
     276                oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
     277                appExpr->acceptMutator( *visitor );
    283278                paramPrefix = oldParamPrefix;
    284279                // write any statements added for recursive specializations into the thunk body
    285                 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
    286                 // restore oldStmts into stmtsToAdd
    287                 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
     280                thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
     281                // restore oldStmts into stmtsToAddBefore
     282                stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
    288283
    289284                // add return (or valueless expression) to the thunk
    290285                Statement *appStmt;
    291                 if ( funType->get_returnVals().empty() ) {
     286                if ( funType->returnVals.empty() ) {
    292287                        appStmt = new ExprStmt( noLabels, appExpr );
    293288                } else {
    294289                        appStmt = new ReturnStmt( noLabels, appExpr );
    295290                } // if
    296                 thunkFunc->get_statements()->get_kids().push_back( appStmt );
     291                thunkFunc->statements->kids.push_back( appStmt );
    297292
    298293                // add thunk definition to queue of statements to add
    299                 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
     294                stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
    300295                // return address of thunk function as replacement expression
    301296                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    304299        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    305300                // create thunks for the explicit parameters
    306                 assert( appExpr->get_function()->has_result() );
    307                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
     301                assert( appExpr->function->result );
     302                FunctionType *function = getFunctionType( appExpr->function->result );
    308303                assert( function );
    309304                std::list< DeclarationWithType* >::iterator formal;
    310305                std::list< Expression* >::iterator actual;
    311306                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    312                         *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
    313                 }
    314         }
    315 
    316         Expression * Specialize::mutate( ApplicationExpr *appExpr ) {
    317                 appExpr->get_function()->acceptMutator( *this );
    318                 mutateAll( appExpr->get_args(), *this );
    319 
     307                        *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
     308                }
     309        }
     310
     311        Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
    320312                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    321313                        // create thunks for the inferred parameters
     
    331323        }
    332324
    333         Expression * Specialize::mutate( AddressExpr *addrExpr ) {
    334                 addrExpr->get_arg()->acceptMutator( *this );
    335                 assert( addrExpr->has_result() );
    336                 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
     325        Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
     326                assert( addrExpr->result );
     327                addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
    337328                return addrExpr;
    338329        }
    339330
    340         Expression * Specialize::mutate( CastExpr *castExpr ) {
    341                 castExpr->get_arg()->acceptMutator( *this );
    342                 if ( castExpr->get_result()->isVoid() ) {
     331        Expression * Specialize::postmutate( CastExpr *castExpr ) {
     332                if ( castExpr->result->isVoid() ) {
    343333                        // can't specialize if we don't have a return value
    344334                        return castExpr;
    345335                }
    346                 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
    347                 if ( specialized != castExpr->get_arg() ) {
     336                Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
     337                if ( specialized != castExpr->arg ) {
    348338                        // assume here that the specialization incorporates the cast
    349339                        return specialized;
     
    353343        }
    354344
    355         // Removing these for now. Richard put these in for some reason, but it's not clear why.
    356         // In particular, copy constructors produce a comma expression, and with this code the parts
    357         // of that comma expression are not specialized, which causes problems.
    358 
    359         // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
    360         //      return logicalExpr;
    361         // }
    362 
    363         // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
    364         //      return condExpr;
    365         // }
    366 
    367         // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
    368         //      return commaExpr;
    369         // }
    370 
    371345        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    372                 Specialize spec;
     346                PassVisitor<Specialize> spec;
    373347                mutateAll( translationUnit, spec );
    374348        }
  • src/GenPoly/module.mk

    raf58ee0 r74bba15  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    1717SRC += GenPoly/Box.cc \
    1818       GenPoly/GenPoly.cc \
    19        GenPoly/PolyMutator.cc \
    2019       GenPoly/ScrubTyVars.cc \
    2120       GenPoly/Lvalue.cc \
     
    2322       GenPoly/CopyParams.cc \
    2423       GenPoly/FindFunction.cc \
    25        GenPoly/DeclMutator.cc \
    2624       GenPoly/InstantiateGeneric.cc
  • src/InitTweak/FixInit.cc

    raf58ee0 r74bba15  
    3636#include "FixGlobalInit.h"             // for fixGlobalInit
    3737#include "GenInit.h"                   // for genCtorDtor
    38 #include "GenPoly/DeclMutator.h"       // for DeclMutator
    3938#include "GenPoly/GenPoly.h"           // for getFunctionType
    40 #include "GenPoly/PolyMutator.h"       // for PolyMutator
    4139#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4240#include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
     
    4644#include "SymTab/Indexer.h"            // for Indexer
    4745#include "SymTab/Mangler.h"            // for Mangler
    48 #include "SynTree/AddStmtVisitor.h"    // for AddStmtVisitor
    4946#include "SynTree/Attribute.h"         // for Attribute
    5047#include "SynTree/Constant.h"          // for Constant
     
    5855#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    5956#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
    60 #include "Tuples/Tuples.h"             // for isTtype
    6157
    6258bool ctordtorp = false; // print all debug
     
    187183                };
    188184
    189                 class FixCopyCtors final : public GenPoly::PolyMutator {
     185                class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
    190186                  public:
    191187                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
     
    194190                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    195191
    196                         typedef GenPoly::PolyMutator Parent;
    197                         using Parent::mutate;
    198                         virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    199                         virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    200                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     192                        Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
     193                        void premutate( StmtExpr * stmtExpr );
     194                        void premutate( UniqueExpr * unqExpr );
    201195
    202196                        UnqCount & unqCount;
     
    243237                };
    244238
    245                 class FixCtorExprs final : public GenPoly::DeclMutator {
    246                   public:
     239                struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer {
    247240                        /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
    248241                        static void fix( std::list< Declaration * > & translationUnit );
    249242
    250                         using GenPoly::DeclMutator::mutate;
    251                         virtual Expression * mutate( ConstructorExpr * ctorExpr ) override;
     243                        Expression * postmutate( ConstructorExpr * ctorExpr );
    252244                };
    253245        } // namespace
     
    316308
    317309                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    318                         FixCopyCtors fixer( unqCount );
     310                        PassVisitor<FixCopyCtors> fixer( unqCount );
    319311                        mutateAll( translationUnit, fixer );
    320312                }
     
    326318
    327319                void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
    328                         FixCtorExprs fixer;
    329                         fixer.mutateDeclarationList( translationUnit );
     320                        PassVisitor<FixCtorExprs> fixer;
     321                        mutateAll( translationUnit, fixer );
    330322                }
    331323
     
    339331                                } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    340332                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    341                                         assert( ftype );
     333                                        assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
    342334                                        if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
    343335                                                Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
     
    368360                }
    369361
    370                 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
    371                         return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
    372                 }
     362                bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); }
    373363
    374364                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     
    407397                        result = result->clone();
    408398                        env->apply( result );
    409                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     399                        ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
    410400                        tmp->get_type()->set_const( false );
    411401
     
    421411                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    422412                        }
     413
     414                        // set a unique name for the temporary once it's certain the call is necessary
     415                        tmp->name = tempNamer.newName();
    423416
    424417                        // replace argument to function call with temporary
     
    450443                                result = result->clone();
    451444                                env->apply( result );
    452                                 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     445                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    453446                                ret->get_type()->set_const( false );
    454447                                impCpCtorExpr->get_returnDecls().push_back( ret );
    455448                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    456449                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
    457                                         // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
     450                                        // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    458451                                        destructRet( ret, impCpCtorExpr );
    459452                                }
     
    472465                                result = result->clone();
    473466                                env->apply( result );
    474                                 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     467                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    475468                                ret->get_type()->set_const( false );
    476469                                stmtExpr->get_returnDecls().push_front( ret );
     
    509502                        } else {
    510503                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    511                                 unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
     504                                unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), nullptr ) );
    512505                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    513506                        }
     
    515508                }
    516509
    517                 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     510                Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    518511                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    519512
    520                         impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    521513                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    522514                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    525517                        // add all temporary declarations and their constructors
    526518                        for ( ObjectDecl * obj : tempDecls ) {
    527                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     519                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    528520                        } // for
    529521                        for ( ObjectDecl * obj : returnDecls ) {
    530                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     522                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    531523                        } // for
    532524
     
    536528                        } // for
    537529
    538                         // xxx - update to work with multiple return values
    539530                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    540531                        Expression * callExpr = impCpCtorExpr->get_callExpr();
     
    569560                }
    570561
    571                 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
     562                void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
    572563                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    573564                        // since temporaries can be shared across sub-expressions, e.g.
    574565                        //   [A, A] f();
    575566                        //   g([A] x, [A] y);
    576                         //   f(g());
     567                        //   g(f());
    577568                        // f is executed once, so the return temporary is shared across the tuple constructors for x and y.
     569                        // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added
     570                        // to the outer context, rather than inside of the statement expression.
     571                        visit_children = false;
    578572                        std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    579573                        for ( Statement *& stmt : stmts ) {
    580                                 stmt = stmt->acceptMutator( *this );
     574                                stmt = stmt->acceptMutator( *visitor );
    581575                        } // for
    582                         // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    583576                        assert( stmtExpr->get_result() );
    584577                        Type * result = stmtExpr->get_result();
    585578                        if ( ! result->isVoid() ) {
    586579                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    587                                         stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     580                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    588581                                } // for
    589582                                // add destructors after current statement
     
    592585                                } // for
    593586                                // must have a non-empty body, otherwise it wouldn't have a result
    594                                 CompoundStmt * body = stmtExpr->get_statements();
    595                                 assert( ! body->get_kids().empty() );
     587                                assert( ! stmts.empty() );
    596588                                assert( ! stmtExpr->get_returnDecls().empty() );
    597                                 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
     589                                stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    598590                                stmtExpr->get_returnDecls().clear();
    599591                                stmtExpr->get_dtors().clear();
     
    601593                        assert( stmtExpr->get_returnDecls().empty() );
    602594                        assert( stmtExpr->get_dtors().empty() );
    603                         return stmtExpr;
    604                 }
    605 
    606                 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
     595                }
     596
     597                void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {
     598                        visit_children = false;
    607599                        unqCount[ unqExpr->get_id() ]--;
    608600                        static std::unordered_map< int, std::list< Statement * > > dtors;
    609601                        static std::unordered_map< int, UniqueExpr * > unqMap;
    610                         static std::unordered_set< int > addDeref;
    611602                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    612603                        if ( unqMap.count( unqExpr->get_id() ) ) {
     
    619610                                        stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    620611                                }
    621                                 if ( addDeref.count( unqExpr->get_id() ) ) {
    622                                         // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
    623                                         return UntypedExpr::createDeref( unqExpr );
    624                                 }
    625                                 return unqExpr;
    626                         }
    627                         FixCopyCtors fixer( unqCount );
     612                                return;
     613                        }
     614                        PassVisitor<FixCopyCtors> fixer( unqCount );
    628615                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    629                         stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
     616                        stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
    630617                        unqMap[unqExpr->get_id()] = unqExpr;
    631618                        if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    632619                                stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    633620                        } else { // remember dtors for last instance of unique expr
    634                                 dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter;
    635                         }
    636                         if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
    637                                 // unique expression is now a dereference, because the inner expression is an lvalue returning function call.
    638                                 // Normalize the expression by dereferencing the unique expression, rather than the inner expression
    639                                 // (i.e. move the dereference out a level)
    640                                 assert( getFunctionName( deref ) == "*?" );
    641                                 unqExpr->set_expr( getCallArg( deref, 0 ) );
    642                                 getCallArg( deref, 0 ) = unqExpr;
    643                                 addDeref.insert( unqExpr->get_id() );
    644                                 return deref;
    645                         }
    646                         return unqExpr;
     621                                dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter;
     622                        }
     623                        return;
    647624                }
    648625
     
    819796                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    820797                                        Statement * dtor = ctorInit->get_dtor();
     798                                        // don't need to call intrinsic dtor, because it does nothing, but
     799                                        // non-intrinsic dtors must be called
    821800                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    822                                                 // don't need to call intrinsic dtor, because it does nothing, but
    823                                                 // non-intrinsic dtors must be called
     801                                                // set dtor location to the object's location for error messages
     802                                                ctorInit->dtor->location = objDecl->location;
    824803                                                reverseDeclOrder.front().push_front( objDecl );
    825804                                        } // if
     
    1012991                                        // skip non-DWT members
    1013992                                        if ( ! field ) continue;
     993                                        // skip non-constructable members
     994                                        if ( ! tryConstruct( field ) ) continue;
    1014995                                        // skip handled members
    1015996                                        if ( ! unhandled.count( field ) ) continue;
     
    11421123                }
    11431124
    1144                 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
     1125                Expression * FixCtorExprs::postmutate( ConstructorExpr * ctorExpr ) {
    11451126                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    11461127                        // xxx - is the size check necessary?
     
    11481129
    11491130                        // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
    1150                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
    1151                         addDeclaration( tmp );
     1131                        ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
     1132                        declsToAddBefore.push_back( tmp );
    11521133
    11531134                        // xxx - this can be TupleAssignExpr now. Need to properly handle this case.
     
    11581139                        delete ctorExpr;
    11591140
     1141                        // build assignment and replace constructor's first argument with new temporary
    11601142                        Expression *& firstArg = callExpr->get_args().front();
    1161 
    1162                         // xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away.
    1163 
    1164                         // generate the type of assignment operator using the type of tmp minus any reference types
    1165                         Type * type = tmp->get_type()->stripReferences();
    1166                         FunctionType * ftype = SymTab::genAssignType( type );
    1167 
    1168                         // generate fake assignment decl and call it using &tmp and &firstArg
    1169                         // since tmp is guaranteed to be a reference and we want to assign pointers
    1170                         FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr );
    1171                         ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) );
    1172                         assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) );
    1173                         Expression * addrArg = new AddressExpr( firstArg );
    1174                         // if firstArg has type T&&, then &firstArg has type T*&.
    1175                         // Cast away the reference to a value type so that the argument
    1176                         // matches the assignment's parameter types
    1177                         if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) {
    1178                                 addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() );
    1179                         }
    1180                         assign->get_args().push_back( addrArg );
     1143                        Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } );
    11811144                        firstArg = new VariableExpr( tmp );
     1145
     1146                        // resolve assignment and dispose of new env
     1147                        Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
     1148                        delete resolvedAssign->env;
     1149                        resolvedAssign->env = nullptr;
     1150                        delete assign;
    11821151
    11831152                        // for constructor expr:
     
    11881157                        //   T & tmp;
    11891158                        //   &tmp = &x, ?{}(tmp), tmp
    1190                         CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1159                        CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11911160                        commaExpr->set_env( env );
    11921161                        return commaExpr;
  • src/InitTweak/GenInit.cc

    raf58ee0 r74bba15  
    2626#include "Common/UniqueName.h"     // for UniqueName
    2727#include "Common/utility.h"        // for ValueGuard, maybeClone
    28 #include "GenPoly/DeclMutator.h"   // for DeclMutator
    2928#include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
    3029#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
     
    6261        };
    6362
    64         struct CtorDtor : public WithGuards, public WithShortCircuiting  {
     63        struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
    6564                /// create constructor and destructor statements for object declarations.
    6665                /// the actual call statements will be added in after the resolver has run
     
    7574                // that need to be constructed or destructed
    7675                void previsit( StructDecl *aggregateDecl );
    77                 void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
    78                 void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
    79                 void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
    80                 void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
    81                 void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
    82                 void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
     76                void previsit( AggregateDecl * ) { visit_children = false; }
     77                void previsit( NamedTypeDecl * ) { visit_children = false; }
     78                void previsit( FunctionType * ) { visit_children = false; }
    8379
    8480                void previsit( CompoundStmt * compoundStmt );
     
    9692        };
    9793
    98         class HoistArrayDimension final : public GenPoly::DeclMutator {
    99           public:
    100                 typedef GenPoly::DeclMutator Parent;
    101 
     94        struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
    10295                /// hoist dimension from array types in object declaration so that it uses a single
    10396                /// const variable of type size_t, so that side effecting array dimensions are only
     
    10598                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    10699
    107           private:
    108                 using Parent::mutate;
    109 
    110                 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
    111                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     100                void premutate( ObjectDecl * objectDecl );
     101                DeclarationWithType * postmutate( ObjectDecl * objectDecl );
     102                void premutate( FunctionDecl *functionDecl );
    112103                // should not traverse into any of these declarations to find objects
    113104                // that need to be constructed or destructed
    114                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; }
    115                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    116                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    117                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    118                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    119                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    120 
    121                 virtual Type* mutate( FunctionType *funcType ) override { return funcType; }
     105                void premutate( AggregateDecl * ) { visit_children = false; }
     106                void premutate( NamedTypeDecl * ) { visit_children = false; }
     107                void premutate( FunctionType * ) { visit_children = false; }
    122108
    123109                void hoist( Type * type );
     
    128114
    129115        void genInit( std::list< Declaration * > & translationUnit ) {
    130                 ReturnFixer::makeReturnTemp( translationUnit );
     116                fixReturnStatements( translationUnit );
    131117                HoistArrayDimension::hoistArrayDimension( translationUnit );
    132118                CtorDtor::generateCtorDtor( translationUnit );
    133119        }
    134120
    135         void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
     121        void fixReturnStatements( std::list< Declaration * > & translationUnit ) {
    136122                PassVisitor<ReturnFixer> fixer;
    137123                mutateAll( translationUnit, fixer );
     
    143129                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    144130                // is being returned
    145                 if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
     131                if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
    146132                        // explicitly construct the return value using the return expression and the retVal object
    147133                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    158144                GuardValue( funcName );
    159145
    160                 ftype = functionDecl->get_functionType();
    161                 funcName = functionDecl->get_name();
     146                ftype = functionDecl->type;
     147                funcName = functionDecl->name;
    162148        }
    163149
     
    165151        // which would be incorrect if it is a side-effecting computation.
    166152        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    167                 HoistArrayDimension hoister;
    168                 hoister.mutateDeclarationList( translationUnit );
    169         }
    170 
    171         DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
     153                PassVisitor<HoistArrayDimension> hoister;
     154                mutateAll( translationUnit, hoister );
     155        }
     156
     157        void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
     158                GuardValue( storageClasses );
    172159                storageClasses = objectDecl->get_storageClasses();
    173                 DeclarationWithType * temp = Parent::mutate( objectDecl );
     160        }
     161
     162        DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
    174163                hoist( objectDecl->get_type() );
    175                 return temp;
     164                return objectDecl;
    176165        }
    177166
     
    194183
    195184                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    196                         addDeclaration( arrayDimension );
     185                        declsToAddBefore.push_back( arrayDimension );
    197186
    198187                        hoist( arrayType->get_base() );
     
    201190        }
    202191
    203         DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
    204                 ValueGuard< bool > oldInFunc( inFunction );
    205                 inFunction = true;
    206                 DeclarationWithType * decl = Parent::mutate( functionDecl );
    207                 return decl;
     192        void HoistArrayDimension::premutate( FunctionDecl * ) {
     193                GuardValue( inFunction );
    208194        }
    209195
     
    214200
    215201        bool CtorDtor::isManaged( Type * type ) const {
    216                 // at least for now, references are never constructed
     202                // references are never constructed
    217203                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
    218204                // need to clear and reset qualifiers when determining if a type is managed
     
    221207                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    222208                        // tuple is also managed if any of its components are managed
    223                         if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
     209                        if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
    224210                                return true;
    225211                        }
     
    305291
    306292        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     293                visit_children = false;  // do not try and construct parameters or forall parameters
    307294                GuardValue( inFunction );
    308295                inFunction = true;
     
    318305                }
    319306
    320                 PassVisitor<CtorDtor> newCtorDtor;
    321                 newCtorDtor.pass = *this;
    322                 maybeAccept( functionDecl->get_statements(), newCtorDtor );
    323                 visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     307                maybeAccept( functionDecl->get_statements(), *visitor );
    324308        }
    325309
     
    340324        }
    341325
    342         void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
     326        void CtorDtor::previsit( CompoundStmt * ) {
    343327                GuardScope( managedTypes );
    344328        }
  • src/InitTweak/GenInit.h

    raf58ee0 r74bba15  
    2525        void genInit( std::list< Declaration * > & translationUnit );
    2626
    27   /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
    28   ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     27        /// Converts return statements into copy constructor calls on the hidden return variable
     28        void fixReturnStatements( std::list< Declaration * > & translationUnit );
     29
     30        /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     31        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
    2932
    3033        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/InitTweak/InitTweak.cc

    raf58ee0 r74bba15  
    1 #include <stddef.h>                // for NULL
    21#include <algorithm>               // for find, all_of
    32#include <cassert>                 // for assertf, assert, strict_dynamic_cast
     
    2322#include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
    2423#include "SynTree/Visitor.h"       // for Visitor, maybeAccept
     24#include "Tuples/Tuples.h"         // for Tuples::isTtype
    2525
    2626class UntypedValofExpr;
     
    184184                        callExpr->get_args().splice( callExpr->get_args().end(), args );
    185185
    186                         *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
     186                        *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
    187187
    188188                        UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
     
    250250        // To accomplish this, generate switch statement, consuming all of expander's elements
    251251        Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    252                 if ( ! init ) return NULL;
     252                if ( ! init ) return nullptr;
    253253                CompoundStmt * block = new CompoundStmt( noLabels );
    254254                build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
    255255                if ( block->get_kids().empty() ) {
    256256                        delete block;
    257                         return NULL;
     257                        return nullptr;
    258258                } else {
    259                         init = NULL; // init was consumed in creating the list init
     259                        init = nullptr; // init was consumed in creating the list init
    260260                        return block;
    261261                }
    262262        }
    263263
    264         Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) {
    265                 return NULL;
     264        Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
     265                return nullptr;
    266266        }
    267267
     
    270270        }
    271271
    272         bool tryConstruct( ObjectDecl * objDecl ) {
     272        bool tryConstruct( DeclarationWithType * dwt ) {
     273                ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
     274                if ( ! objDecl ) return false;
    273275                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    274                         (objDecl->get_init() == NULL ||
    275                                 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
    276                         && ! objDecl->get_storageClasses().is_extern;
     276                        (objDecl->get_init() == nullptr ||
     277                                ( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() ))
     278                        && ! objDecl->get_storageClasses().is_extern
     279                        && isConstructable( objDecl->type );
     280        }
     281
     282        bool isConstructable( Type * type ) {
     283                return ! dynamic_cast< VarArgsType * >( type ) && ! dynamic_cast< ReferenceType * >( type ) && ! dynamic_cast< FunctionType * >( type ) && ! Tuples::isTtype( type );
    277284        }
    278285
     
    314321                collectCtorDtorCalls( stmt, matches );
    315322                assert( matches.size() <= 1 );
    316                 return matches.size() == 1 ? matches.front() : NULL;
     323                return matches.size() == 1 ? matches.front() : nullptr;
    317324        }
    318325
     
    359366        ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
    360367                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
    361                 if ( ! appExpr ) return NULL;
     368                if ( ! appExpr ) return nullptr;
    362369                DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
    363370                assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
    364371                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    365372                // will call all member dtors, and some members may have a user defined dtor.
    366                 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
     373                return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;
    367374        }
    368375
     
    482489                        return refType->get_base();
    483490                } else {
    484                         return NULL;
     491                        return nullptr;
    485492                }
    486493        }
     
    488495        Type * isPointerType( Type * type ) {
    489496                if ( getPointerBase( type ) ) return type;
    490                 else return NULL;
     497                else return nullptr;
    491498        }
    492499
  • src/InitTweak/InitTweak.h

    raf58ee0 r74bba15  
    3333        std::list< Expression * > makeInitList( Initializer * init );
    3434
    35         /// True if the resolver should try to construct objDecl
    36         bool tryConstruct( ObjectDecl * objDecl );
     35        /// True if the resolver should try to construct dwt
     36        bool tryConstruct( DeclarationWithType * dwt );
     37
     38        /// True if the type can have a user-defined constructor
     39        bool isConstructable( Type * t );
    3740
    3841        /// True if the Initializer contains designations
  • src/Makefile.in

    raf58ee0 r74bba15  
    172172        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    173173        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
    174         GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) \
    175174        GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \
    176175        GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
     
    178177        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    179178        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
    180         GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    181179        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    182180        InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
     
    253251        SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
    254252        SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
    255         SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT) \
    256253        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    257254        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
     
    497494        ControlStruct/ForExprMutator.cc \
    498495        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    499         GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
    500         GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    501         GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    502         GenPoly/DeclMutator.cc GenPoly/InstantiateGeneric.cc \
     496        GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
     497        GenPoly/Specialize.cc GenPoly/CopyParams.cc \
     498        GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \
    503499        InitTweak/GenInit.cc InitTweak/FixInit.cc \
    504500        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
     
    535531        SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    536532        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
    537         SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
    538         SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
    539         Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    540         Tuples/Explode.cc Virtual/ExpandCasts.cc
     533        SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
     534        SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
     535        Tuples/TupleExpansion.cc Tuples/Explode.cc \
     536        Virtual/ExpandCasts.cc
    541537MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    542538        ${cfa_cpplib_PROGRAMS}}
     
    717713GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
    718714        GenPoly/$(DEPDIR)/$(am__dirstamp)
    719 GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
    720         GenPoly/$(DEPDIR)/$(am__dirstamp)
    721715GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
    722716        GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    729723GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
    730724        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
    731 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
    732         GenPoly/$(DEPDIR)/$(am__dirstamp)
    733725GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    734726        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    929921SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
    930922        SynTree/$(DEPDIR)/$(am__dirstamp)
    931 SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT):  \
    932         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    933923SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    934924        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
     
    1008998@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@
    1009999@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@
    1010 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po@am__quote@
    10111000@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    10121001@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
    10131002@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    10141003@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@
    1015 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@
    10161004@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    10171005@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     
    10561044@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@
    10571045@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@
    1058 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po@am__quote@
    10591046@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
    10601047@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@
     
    14501437@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi`
    14511438
    1452 GenPoly/driver_cfa_cpp-PolyMutator.o: GenPoly/PolyMutator.cc
    1453 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
    1454 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
    1455 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.o' libtool=no @AMDEPBACKSLASH@
    1456 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1457 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
    1458 
    1459 GenPoly/driver_cfa_cpp-PolyMutator.obj: GenPoly/PolyMutator.cc
    1460 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
    1461 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
    1462 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.obj' libtool=no @AMDEPBACKSLASH@
    1463 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1464 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
    1465 
    14661439GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc
    14671440@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc
     
    15341507@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    15351508
    1536 GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
    1537 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
    1538 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
    1539 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@
    1540 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1541 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
    1542 
    1543 GenPoly/driver_cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc
    1544 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
    1545 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
    1546 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@
    1547 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1548 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
    1549 
    15501509GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    15511510@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
     
    25832542@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    25842543@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
    2585 
    2586 SynTree/driver_cfa_cpp-AddStmtVisitor.o: SynTree/AddStmtVisitor.cc
    2587 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
    2588 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
    2589 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.o' libtool=no @AMDEPBACKSLASH@
    2590 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2591 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
    2592 
    2593 SynTree/driver_cfa_cpp-AddStmtVisitor.obj: SynTree/AddStmtVisitor.cc
    2594 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
    2595 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
    2596 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.obj' libtool=no @AMDEPBACKSLASH@
    2597 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2598 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
    25992544
    26002545SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
  • src/Parser/StatementNode.cc

    raf58ee0 r74bba15  
    234234                target,
    235235                maybeMoveBuild<Statement >( stmt ),
    236                 maybeMoveBuild<Expression>( when )
     236                notZeroExpr( maybeMoveBuild<Expression>( when ) )
    237237        });
    238238
     
    250250        delete targetExpr;
    251251
    252         node->clauses.push_back( WaitForStmt::Clause{
     252        node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{
    253253                std::move( target ),
    254254                maybeMoveBuild<Statement >( stmt ),
    255                 maybeMoveBuild<Expression>( when )
     255                notZeroExpr( maybeMoveBuild<Expression>( when ) )
    256256        });
    257257
     
    265265                node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    266266                node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    267                 node->timeout.condition = maybeMoveBuild<Expression>( when    );
     267                node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    268268        }
    269269        else {
    270                 node->orelse.statement  = maybeMoveBuild<Statement >( stmt    );
    271                 node->orelse.condition  = maybeMoveBuild<Expression>( when    );
     270                node->orelse.statement  = maybeMoveBuild<Statement >( stmt );
     271                node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    272272        }
    273273
     
    280280        node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    281281        node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    282         node->timeout.condition = maybeMoveBuild<Expression>( when    );
     282        node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    283283
    284284        node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
    285         node->orelse.condition = maybeMoveBuild<Expression>( else_when );
     285        node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
    286286
    287287        return node;
    288288}
    289 
    290 // WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) {
    291 //       return WaitForStmt::Clause{
    292 
    293 //       };
    294 // }
    295289
    296290Statement *build_compound( StatementNode *first ) {
  • src/Parser/parserutility.cc

    raf58ee0 r74bba15  
    2929
    3030Expression *notZeroExpr( Expression *orig ) {
     31        if( !orig ) return nullptr;
    3132        UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
    3233        comparison->get_args().push_back( orig );
  • src/ResolvExpr/AlternativeFinder.cc

    raf58ee0 r74bba15  
    144144                        expr->get_result()->accept( global_renamer );
    145145                }
    146 
    147                 void referenceToRvalueConversion( Expression *& expr ) {
    148                         if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
    149                                 // cast away reference from expr
    150                                 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
    151                         }
    152                 }
    153146        } // namespace
     147
     148        void referenceToRvalueConversion( Expression *& expr ) {
     149                if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     150                        // cast away reference from expr
     151                        expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
     152                }
     153        }
    154154
    155155        template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/AlternativeFinder.h

    raf58ee0 r74bba15  
    5050                const SymTab::Indexer &get_indexer() const { return indexer; }
    5151                const TypeEnvironment &get_environ() const { return env; }
     52
     53                /// Runs a new alternative finder on each element in [begin, end)
     54                /// and writes each alternative finder to out.
     55                template< typename InputIterator, typename OutputIterator >
     56                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    5257          private:
    5358                virtual void visit( ApplicationExpr *applicationExpr );
     
    8186                virtual void visit( StmtExpr *stmtExpr );
    8287                virtual void visit( UntypedInitExpr *initExpr );
    83                 /// Runs a new alternative finder on each element in [begin, end)
    84                 /// and writes each alternative finder to out.
    85                 template< typename InputIterator, typename OutputIterator >
    86                 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    8788
    8889                /// Adds alternatives for anonymous members
     
    108109
    109110        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
     111        void referenceToRvalueConversion( Expression *& expr );
    110112
    111113        template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/Resolver.cc

    raf58ee0 r74bba15  
    4040#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4141#include "typeops.h"                     // for extractResultType
     42#include "Unify.h"                       // for unify
    4243
    4344using namespace std;
     
    7172                void previsit( ThrowStmt *throwStmt );
    7273                void previsit( CatchStmt *catchStmt );
     74                void previsit( WaitForStmt * stmt );
    7375
    7476                void previsit( SingleInit *singleInit );
     
    9395                PassVisitor<Resolver> resolver;
    9496                acceptAll( translationUnit, resolver );
     97        }
     98
     99        void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     100                PassVisitor<Resolver> resolver( indexer );
     101                maybeAccept( decl, resolver );
    95102        }
    96103
     
    116123        }
    117124
     125        Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     126                TypeEnvironment env;
     127                AlternativeFinder finder( indexer, env );
     128                finder.find( untyped );
     129                #if 0
     130                if ( finder.get_alternatives().size() != 1 ) {
     131                        std::cout << "untyped expr is ";
     132                        untyped->print( std::cout );
     133                        std::cout << std::endl << "alternatives are:";
     134                        for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     135                                i->print( std::cout );
     136                        } // for
     137                } // if
     138                #endif
     139                assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
     140                Alternative &choice = finder.get_alternatives().front();
     141                Expression *newExpr = choice.expr->clone();
     142                finishExpr( newExpr, choice.env );
     143                return newExpr;
     144        }
     145
    118146        namespace {
    119                 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    120                         TypeEnvironment env;
    121                         AlternativeFinder finder( indexer, env );
    122                         finder.find( untyped );
    123 #if 0
    124                         if ( finder.get_alternatives().size() != 1 ) {
    125                                 std::cout << "untyped expr is ";
    126                                 untyped->print( std::cout );
    127                                 std::cout << std::endl << "alternatives are:";
    128                                 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    129                                         i->print( std::cout );
    130                                 } // for
    131                         } // if
    132 #endif
    133                         assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
    134                         Alternative &choice = finder.get_alternatives().front();
    135                         Expression *newExpr = choice.expr->clone();
    136                         finishExpr( newExpr, choice.env );
    137                         return newExpr;
    138                 }
    139 
    140147                bool isIntegralType( Type *type ) {
    141148                        if ( dynamic_cast< EnumInstType * >( type ) ) {
     
    391398        }
    392399
     400        inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {
     401                if( !expr ) return;
     402                Expression * newExpr = findSingleExpression( expr, indexer );
     403                delete expr;
     404                expr = newExpr;
     405        }
     406
     407        inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {
     408                if( !expr ) return;
     409                Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );
     410                delete expr;
     411                expr = newExpr;
     412        }
     413
     414        template< typename iterator_t >
     415        inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {
     416                while( it != end && !(*it)->get_type()->get_mutex() ) {
     417                        it++;
     418                }
     419
     420                return it != end;
     421        }
     422
     423        void Resolver::previsit( WaitForStmt * stmt ) {
     424                visit_children = false;
     425
     426                // Resolve all clauses first
     427                for( auto& clause : stmt->clauses ) {
     428
     429                        TypeEnvironment env;
     430                        AlternativeFinder funcFinder( indexer, env );
     431
     432                        // Find all alternatives for a function in canonical form
     433                        funcFinder.findWithAdjustment( clause.target.function );
     434
     435                        if ( funcFinder.get_alternatives().empty() ) {
     436                                stringstream ss;
     437                                ss << "Use of undeclared indentifier '";
     438                                ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;
     439                                ss << "' in call to waitfor";
     440                                throw SemanticError( ss.str() );
     441                        }
     442
     443                        // Find all alternatives for all arguments in canonical form
     444                        std::list< AlternativeFinder > argAlternatives;
     445                        funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );
     446
     447                        // List all combinations of arguments
     448                        std::list< AltList > possibilities;
     449                        combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     450
     451                        AltList                func_candidates;
     452                        std::vector< AltList > args_candidates;
     453
     454                        // For every possible function :
     455                        //      try matching the arguments to the parameters
     456                        //      not the other way around because we have more arguments than parameters
     457                        SemanticError errors;
     458                        for ( Alternative & func : funcFinder.get_alternatives() ) {
     459                                try {
     460                                        PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );
     461                                        if( !pointer ) {
     462                                                throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );
     463                                        }
     464
     465                                        FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );
     466                                        if( !function ) {
     467                                                throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );
     468                                        }
     469
     470
     471                                        {
     472                                                auto param     = function->parameters.begin();
     473                                                auto param_end = function->parameters.end();
     474
     475                                                if( !advance_to_mutex( param, param_end ) ) {
     476                                                        throw SemanticError("candidate function not viable: no mutex parameters\n", function);
     477                                                }
     478                                        }
     479
     480                                        Alternative newFunc( func );
     481                                        // Strip reference from function
     482                                        referenceToRvalueConversion( newFunc.expr );
     483
     484                                        // For all the set of arguments we have try to match it with the parameter of the current function alternative
     485                                        for ( auto & argsList : possibilities ) {
     486
     487                                                try {
     488                                                        // Declare data structures need for resolution
     489                                                        OpenVarSet openVars;
     490                                                        AssertionSet resultNeed, resultHave;
     491                                                        TypeEnvironment resultEnv;
     492
     493                                                        // Load type variables from arguemnts into one shared space
     494                                                        simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );
     495
     496                                                        // Make sure we don't widen any existing bindings
     497                                                        for ( auto & i : resultEnv ) {
     498                                                                i.allowWidening = false;
     499                                                        }
     500
     501                                                        // Find any unbound type variables
     502                                                        resultEnv.extractOpenVars( openVars );
     503
     504                                                        auto param     = function->parameters.begin();
     505                                                        auto param_end = function->parameters.end();
     506
     507                                                        // For every arguments of its set, check if it matches one of the parameter
     508                                                        // The order is important
     509                                                        for( auto & arg : argsList ) {
     510
     511                                                                // Ignore non-mutex arguments
     512                                                                if( !advance_to_mutex( param, param_end ) ) {
     513                                                                        // We ran out of parameters but still have arguments
     514                                                                        // this function doesn't match
     515                                                                        throw SemanticError("candidate function not viable: too many mutex arguments\n", function);
     516                                                                }
     517
     518                                                                // Check if the argument matches the parameter type in the current scope
     519                                                                if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {
     520                                                                        // Type doesn't match
     521                                                                        stringstream ss;
     522                                                                        ss << "candidate function not viable: no known convertion from '";
     523                                                                        arg.expr->get_result()->print( ss );
     524                                                                        ss << "' to '";
     525                                                                        (*param)->get_type()->print( ss );
     526                                                                        ss << "'\n";
     527                                                                        throw SemanticError(ss.str(), function);
     528                                                                }
     529
     530                                                                param++;
     531                                                        }
     532
     533                                                        // All arguments match !
     534
     535                                                        // Check if parameters are missing
     536                                                        if( advance_to_mutex( param, param_end ) ) {
     537                                                                // We ran out of arguments but still have parameters left
     538                                                                // this function doesn't match
     539                                                                throw SemanticError("candidate function not viable: too few mutex arguments\n", function);
     540                                                        }
     541
     542                                                        // All parameters match !
     543
     544                                                        // Finish the expressions to tie in the proper environments
     545                                                        finishExpr( newFunc.expr, resultEnv );
     546                                                        for( Alternative & alt : argsList ) {
     547                                                                finishExpr( alt.expr, resultEnv );
     548                                                        }
     549
     550                                                        // This is a match store it and save it for later
     551                                                        func_candidates.push_back( newFunc );
     552                                                        args_candidates.push_back( argsList );
     553
     554                                                }
     555                                                catch( SemanticError &e ) {
     556                                                        errors.append( e );
     557                                                }
     558                                        }
     559                                }
     560                                catch( SemanticError &e ) {
     561                                        errors.append( e );
     562                                }
     563                        }
     564
     565                        // Make sure we got the right number of arguments
     566                        if( func_candidates.empty() )    { SemanticError top( "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
     567                        if( args_candidates.empty() )    { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
     568                        if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
     569                        if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
     570
     571
     572                        // Swap the results from the alternative with the unresolved values.
     573                        // Alternatives will handle deletion on destruction
     574                        std::swap( clause.target.function, func_candidates.front().expr );
     575                        for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {
     576                                std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );
     577                        }
     578
     579                        // Resolve the conditions as if it were an IfStmt
     580                        // Resolve the statments normally
     581                        resolveAsIf( clause.condition, this->indexer );
     582                        clause.statement->accept( *visitor );
     583                }
     584
     585
     586                if( stmt->timeout.statement ) {
     587                        // Resolve the timeout as an size_t for now
     588                        // Resolve the conditions as if it were an IfStmt
     589                        // Resolve the statments normally
     590                        resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
     591                        resolveAsIf  ( stmt->timeout.condition, this->indexer );
     592                        stmt->timeout.statement->accept( *visitor );
     593                }
     594
     595                if( stmt->orelse.statement ) {
     596                        // Resolve the conditions as if it were an IfStmt
     597                        // Resolve the statments normally
     598                        resolveAsIf( stmt->orelse.condition, this->indexer );
     599                        stmt->orelse.statement->accept( *visitor );
     600                }
     601        }
     602
    393603        template< typename T >
    394604        bool isCharType( T t ) {
  • src/ResolvExpr/Resolver.h

    raf58ee0 r74bba15  
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
     31        void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
    3132        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    3233        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
     34        Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );
    3335        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3436        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    raf58ee0 r74bba15  
    123123                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    124124                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    125 ///       std::cout << "adding " << *theVar;
     125///       std::cerr << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cout << " bound to ";
    128 ///         theClass->type->print( std::cout );
    129 ///         std::cout << std::endl;
     127///         std::cerr << " bound to ";
     128///         theClass->type->print( std::cerr );
     129///         std::cerr << std::endl;
    130130                                        sub.add( *theVar, theClass->type );
    131131                                } else if ( theVar != theClass->vars.begin() ) {
    132132                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    133 ///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
  • src/SymTab/Autogen.cc

    raf58ee0 r74bba15  
    1616#include "Autogen.h"
    1717
    18 #include <cstddef>                 // for NULL
    1918#include <algorithm>               // for count_if
    2019#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2726#include "AddVisit.h"              // for addVisit
    2827#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
     28#include "Common/PassVisitor.h"    // for PassVisitor
    2929#include "Common/ScopedMap.h"      // for ScopedMap<>::const_iterator, Scope...
    3030#include "Common/utility.h"        // for cloneAll, operator+
    31 #include "GenPoly/DeclMutator.h"   // for DeclMutator
    3231#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
     32#include "InitTweak/GenInit.h"     // for fixReturnStatements
     33#include "ResolvExpr/Resolver.h"   // for resolveDecl
    3334#include "SymTab/Mangler.h"        // for Mangler
    3435#include "SynTree/Attribute.h"     // For Attribute
     
    5354        };
    5455
    55         class AutogenerateRoutines final : public Visitor {
    56             template< typename Visitor >
    57             friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    58             template< typename Visitor >
    59             friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor );
    60           public:
    61                 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    62 
    63                 typedef Visitor Parent;
    64                 using Parent::visit;
    65 
     56        struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
    6657                AutogenerateRoutines();
    6758
    68                 virtual void visit( EnumDecl *enumDecl );
    69                 virtual void visit( StructDecl *structDecl );
    70                 virtual void visit( UnionDecl *structDecl );
    71                 virtual void visit( TypeDecl *typeDecl );
    72                 virtual void visit( TraitDecl *ctxDecl );
    73                 virtual void visit( FunctionDecl *functionDecl );
    74 
    75                 virtual void visit( FunctionType *ftype );
    76                 virtual void visit( PointerType *ftype );
    77 
    78                 virtual void visit( CompoundStmt *compoundStmt );
    79                 virtual void visit( SwitchStmt *switchStmt );
     59                void previsit( EnumDecl * enumDecl );
     60                void previsit( StructDecl * structDecl );
     61                void previsit( UnionDecl * structDecl );
     62                void previsit( TypeDecl * typeDecl );
     63                void previsit( TraitDecl * traitDecl );
     64                void previsit( FunctionDecl * functionDecl );
     65
     66                void previsit( FunctionType * ftype );
     67                void previsit( PointerType * ptype );
     68
     69                void previsit( CompoundStmt * compoundStmt );
    8070
    8171          private:
    82                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    83 
    84                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    85                 std::set< std::string > structsDone;
     72                GenPoly::ScopedSet< std::string > structsDone;
    8673                unsigned int functionNesting = 0;     // current level of nested functions
    8774                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    9380
    9481        /// generates routines for tuple types.
    95         /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit
    96         /// or anything we currently have that supports adding new declarations for visitors
    97         class AutogenTupleRoutines : public GenPoly::DeclMutator {
    98           public:
    99                 typedef GenPoly::DeclMutator Parent;
    100                 using Parent::mutate;
    101 
    102                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    103 
    104                 virtual Type * mutate( TupleType *tupleType );
    105 
    106                 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt );
     82        struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting {
     83                void previsit( FunctionDecl *functionDecl );
     84
     85                void postvisit( TupleType *tupleType );
     86
     87                void previsit( CompoundStmt *compoundStmt );
    10788
    10889          private:
     
    11293
    11394        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    114                 AutogenerateRoutines generator;
    115                 acceptAndAdd( translationUnit, generator );
     95                PassVisitor<AutogenerateRoutines> generator;
     96                acceptAll( translationUnit, generator );
    11697
    11798                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
    11899                // AutogenTupleRoutines tupleGenerator;
    119                 // tupleGenerator.mutateDeclarationList( translationUnit );
     100                // acceptAll( translationUnit, tupleGenerator );
    120101        }
    121102
    122103        bool isUnnamedBitfield( ObjectDecl * obj ) {
    123                 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
     104                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    124105        }
    125106
     
    128109                FunctionDecl * decl = functionDecl->clone();
    129110                delete decl->get_statements();
    130                 decl->set_statements( NULL );
     111                decl->set_statements( nullptr );
    131112                declsToAdd.push_back( decl );
    132113                decl->fixUniqueId();
     
    339320                                assert( ! func->get_functionType()->get_parameters().empty() );
    340321                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    341                                 ObjectDecl * srcParam = NULL;
     322                                ObjectDecl * srcParam = nullptr;
    342323                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    343324                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    346327                                assert( dstParam );
    347328
    348                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     329                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    349330                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    350331                        } // if
     
    385366                                } else {
    386367                                        // no matching parameter, initialize field with default ctor
    387                                         makeStructMemberOp( dstParam, NULL, field, func );
     368                                        makeStructMemberOp( dstParam, nullptr, field, func );
    388369                                }
    389370                        }
     
    401382        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    402383                // Builtins do not use autogeneration.
    403                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    404                          aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
     384                if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
    405385                        return;
    406386                }
    407387
    408388                // Make function polymorphic in same parameters as generic struct, if applicable
    409                 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     389                const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    410390
    411391                // generate each of the functions based on the supplied FuncData objects
     
    572552                // the order here determines the order that these functions are generated.
    573553                // assignment should come last since it uses copy constructor in return.
    574                 data.push_back( FuncData( "?{}", genDefaultType, constructable ) );
    575                 data.push_back( FuncData( "?{}", genCopyType, copyable ) );
    576                 data.push_back( FuncData( "^?{}", genDefaultType, destructable ) );
    577                 data.push_back( FuncData( "?=?", genAssignType, assignable ) );
    578         }
    579 
    580         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
     554                data.emplace_back( "?{}", genDefaultType, constructable );
     555                data.emplace_back( "?{}", genCopyType, copyable );
     556                data.emplace_back( "^?{}", genDefaultType, destructable );
     557                data.emplace_back( "?=?", genAssignType, assignable );
     558        }
     559
     560        void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
     561                visit_children = false;
    581562                if ( ! enumDecl->get_members().empty() ) {
    582563                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    586567        }
    587568
    588         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    589                 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    590                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    591                         for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
     569        void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
     570                visit_children = false;
     571                if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
     572                        StructInstType structInst( Type::Qualifiers(), structDecl->name );
     573                        for ( TypeDecl * typeDecl : structDecl->parameters ) {
    592574                                // need to visit assertions so that they are added to the appropriate maps
    593                                 acceptAll( typeDecl->get_assertions(), *this );
    594                                 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
     575                                acceptAll( typeDecl->assertions, *visitor );
     576                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    595577                        }
    596578                        structInst.set_baseStruct( structDecl );
    597579                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    598                         structsDone.insert( structDecl->get_name() );
     580                        structsDone.insert( structDecl->name );
    599581                } // if
    600582        }
    601583
    602         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     584        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
     585                visit_children = false;
    603586                if ( ! unionDecl->get_members().empty() ) {
    604587                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    619602
    620603        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    621         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     604        void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
     605                visit_children = false;
    622606                if ( ! typeDecl->base ) return;
    623607
     
    664648        }
    665649
    666         void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    667                 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    668                         statements.insert( i, new DeclStmt( noLabels, *decl ) );
    669                 } // for
    670                 declsToAdd.clear();
    671         }
    672 
    673         void AutogenerateRoutines::visit( FunctionType *) {
     650        void AutogenerateRoutines::previsit( FunctionType *) {
    674651                // ensure that we don't add assignment ops for types defined as part of the function
    675         }
    676 
    677         void AutogenerateRoutines::visit( PointerType *) {
     652                visit_children = false;
     653        }
     654
     655        void AutogenerateRoutines::previsit( PointerType *) {
    678656                // ensure that we don't add assignment ops for types defined as part of the pointer
    679         }
    680 
    681         void AutogenerateRoutines::visit( TraitDecl *) {
     657                visit_children = false;
     658        }
     659
     660        void AutogenerateRoutines::previsit( TraitDecl * ) {
    682661                // ensure that we don't add assignment ops for types defined as part of the trait
    683         }
    684 
    685         template< typename StmtClass >
    686         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
    687                 std::set< std::string > oldStructs = structsDone;
    688                 addVisit( stmt, *this );
    689                 structsDone = oldStructs;
    690         }
    691 
    692         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     662                visit_children = false;
     663        }
     664
     665        void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
     666                visit_children = false;
    693667                // record the existence of this function as appropriate
    694668                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    697671                insert( functionDecl, destructable, InitTweak::isDestructor );
    698672
    699                 maybeAccept( functionDecl->get_functionType(), *this );
     673                maybeAccept( functionDecl->type, *visitor );
    700674                functionNesting += 1;
    701                 maybeAccept( functionDecl->get_statements(), *this );
     675                maybeAccept( functionDecl->statements, *visitor );
    702676                functionNesting -= 1;
    703677        }
    704678
    705         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
    706                 constructable.beginScope();
    707                 assignable.beginScope();
    708                 copyable.beginScope();
    709                 destructable.beginScope();
    710                 visitStatement( compoundStmt );
    711                 constructable.endScope();
    712                 assignable.endScope();
    713                 copyable.endScope();
    714                 destructable.endScope();
    715         }
    716 
    717         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    718                 visitStatement( switchStmt );
     679        void AutogenerateRoutines::previsit( CompoundStmt * ) {
     680                GuardScope( constructable );
     681                GuardScope( assignable );
     682                GuardScope( copyable );
     683                GuardScope( destructable );
     684                GuardScope( structsDone );
    719685        }
    720686
     
    734700        }
    735701
    736         Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
    737                 tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
     702        void AutogenTupleRoutines::postvisit( TupleType * tupleType ) {
    738703                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
    739                 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
     704                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return;
    740705                seenTuples.insert( mangleName );
    741706
     
    785750                makeTupleFunctionBody( dtorDecl );
    786751
    787                 addDeclaration( ctorDecl );
    788                 addDeclaration( copyCtorDecl );
    789                 addDeclaration( dtorDecl );
    790                 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return
    791 
    792                 return tupleType;
    793         }
    794 
    795         DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) {
    796                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     752                declsToAddBefore.push_back( ctorDecl );
     753                declsToAddBefore.push_back( copyCtorDecl );
     754                declsToAddBefore.push_back( dtorDecl );
     755                declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
     756        }
     757
     758        void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) {
     759                visit_children = false;
     760                maybeAccept( functionDecl->type, *visitor );
    797761                functionNesting += 1;
    798                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     762                maybeAccept( functionDecl->statements, *visitor );
    799763                functionNesting -= 1;
    800                 return functionDecl;
    801         }
    802 
    803         CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) {
    804                 seenTuples.beginScope();
    805                 compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) );
    806                 seenTuples.endScope();
    807                 return compoundStmt;
     764        }
     765
     766        void AutogenTupleRoutines::previsit( CompoundStmt * ) {
     767                GuardScope( seenTuples );
    808768        }
    809769} // SymTab
  • src/SymTab/FixFunction.cc

    raf58ee0 r74bba15  
    2727
    2828        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
     29                // can't delete function type because it may contain assertions, so transfer ownership to new object
    2930                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() );
    3031                functionDecl->get_attributes().clear();
    31                 // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr
    32                 functionDecl->set_type( functionDecl->get_type()->clone() );
     32                functionDecl->type = nullptr;
    3333                delete functionDecl;
    3434                return pointer;
  • src/SymTab/Indexer.cc

    raf58ee0 r74bba15  
    4040
    4141namespace SymTab {
    42         struct NewScope {
    43                 NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }
    44                 ~NewScope() { indexer.leaveScope(); }
    45                 SymTab::Indexer & indexer;
    46         };
    47 
    48         template< typename TreeType, typename VisitorType >
    49         inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
    50                 visitor.enterScope();
    51                 maybeAccept( tree, visitor );
    52                 visitor.leaveScope();
    53         }
    54 
    5542        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    5643        typedef std::unordered_map< std::string, MangleTable > IdTable;
     
    198185        }
    199186
    200         Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
    201 
    202         Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
    203 
    204         Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
     187        Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
     188
     189        Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
     190
     191        Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
    205192                that.tables = 0;
    206193        }
  • src/SymTab/Indexer.h

    raf58ee0 r74bba15  
    2626        class Indexer {
    2727          public:
    28                 explicit Indexer( bool useDebug = false );
     28                explicit Indexer();
    2929
    3030                Indexer( const Indexer &that );
     
    7676                void addTrait( TraitDecl *decl );
    7777
     78                bool doDebug = false; ///< Display debugging trace?
    7879          private:
    7980                struct Impl;
     
    8182                Impl *tables;         ///< Copy-on-write instance of table data structure
    8283                unsigned long scope;  ///< Scope index of this pointer
    83                 bool doDebug;         ///< Display debugging trace?
    8484
    8585                /// Takes a new ref to a table (returns null if null)
  • src/SymTab/Mangler.cc

    raf58ee0 r74bba15  
    3131
    3232namespace SymTab {
    33         std::string Mangler::mangleType( Type *ty ) {
     33        std::string Mangler::mangleType( Type * ty ) {
    3434                Mangler mangler( false, true );
    3535                maybeAccept( ty, mangler );
     
    4848        }
    4949
    50         void Mangler::mangleDecl( DeclarationWithType *declaration ) {
     50        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
    5151                bool wasTopLevel = isTopLevel;
    5252                if ( isTopLevel ) {
     
    7979        }
    8080
    81         void Mangler::visit( ObjectDecl *declaration ) {
     81        void Mangler::visit( ObjectDecl * declaration ) {
    8282                mangleDecl( declaration );
    8383        }
    8484
    85         void Mangler::visit( FunctionDecl *declaration ) {
     85        void Mangler::visit( FunctionDecl * declaration ) {
    8686                mangleDecl( declaration );
    8787        }
    8888
    89         void Mangler::visit( VoidType *voidType ) {
     89        void Mangler::visit( VoidType * voidType ) {
    9090                printQualifiers( voidType );
    9191                mangleName << "v";
    9292        }
    9393
    94         void Mangler::visit( BasicType *basicType ) {
     94        void Mangler::visit( BasicType * basicType ) {
    9595                static const char *btLetter[] = {
    9696                        "b",    // Bool
     
    121121        }
    122122
    123         void Mangler::visit( PointerType *pointerType ) {
     123        void Mangler::visit( PointerType * pointerType ) {
    124124                printQualifiers( pointerType );
    125125                mangleName << "P";
     
    127127        }
    128128
    129         void Mangler::visit( ArrayType *arrayType ) {
     129        void Mangler::visit( ArrayType * arrayType ) {
    130130                // TODO: encode dimension
    131131                printQualifiers( arrayType );
     
    134134        }
    135135
    136         void Mangler::visit( ReferenceType *refType ) {
     136        void Mangler::visit( ReferenceType * refType ) {
    137137                printQualifiers( refType );
    138138                mangleName << "R";
     
    149149        }
    150150
    151         void Mangler::visit( FunctionType *functionType ) {
     151        void Mangler::visit( FunctionType * functionType ) {
    152152                printQualifiers( functionType );
    153153                mangleName << "F";
     
    160160        }
    161161
    162         void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
     162        void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
    163163                printQualifiers( refType );
    164164
     
    166166        }
    167167
    168         void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
     168        void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {
    169169                printQualifiers( refType );
    170170
     
    189189        }
    190190
    191         void Mangler::visit( StructInstType *aggregateUseType ) {
     191        void Mangler::visit( StructInstType * aggregateUseType ) {
    192192                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
    193193                else mangleRef( aggregateUseType, "s" );
    194194        }
    195195
    196         void Mangler::visit( UnionInstType *aggregateUseType ) {
     196        void Mangler::visit( UnionInstType * aggregateUseType ) {
    197197                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
    198198                else mangleRef( aggregateUseType, "u" );
    199199        }
    200200
    201         void Mangler::visit( EnumInstType *aggregateUseType ) {
     201        void Mangler::visit( EnumInstType * aggregateUseType ) {
    202202                mangleRef( aggregateUseType, "e" );
    203203        }
    204204
    205         void Mangler::visit( TypeInstType *typeInst ) {
     205        void Mangler::visit( TypeInstType * typeInst ) {
    206206                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    207207                if ( varNum == varNums.end() ) {
     
    231231        }
    232232
    233         void Mangler::visit( TupleType *tupleType ) {
     233        void Mangler::visit( TupleType * tupleType ) {
    234234                printQualifiers( tupleType );
    235235                mangleName << "T";
    236                 acceptAll( tupleType->get_types(), *this );
     236                acceptAll( tupleType->types, *this );
    237237                mangleName << "_";
    238238        }
    239239
    240         void Mangler::visit( VarArgsType *varArgsType ) {
     240        void Mangler::visit( VarArgsType * varArgsType ) {
    241241                printQualifiers( varArgsType );
    242242                mangleName << "VARGS";
    243243        }
    244244
    245         void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
     245        void Mangler::visit( ZeroType * ) {
    246246                mangleName << "Z";
    247247        }
    248248
    249         void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
     249        void Mangler::visit( OneType * ) {
    250250                mangleName << "O";
    251251        }
    252252
    253         void Mangler::visit( TypeDecl *decl ) {
     253        void Mangler::visit( TypeDecl * decl ) {
    254254                static const char *typePrefix[] = { "BT", "BD", "BF" };
    255                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
     255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
    256256        }
    257257
     
    262262        }
    263263
    264         void Mangler::printQualifiers( Type *type ) {
     264        void Mangler::printQualifiers( Type * type ) {
    265265                // skip if not including qualifiers
    266266                if ( typeMode ) return;
     
    270270                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    271271                        mangleName << "A";
    272                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     272                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    273273                                switch ( (*i)->get_kind() ) {
    274274                                  case TypeDecl::Any:
     
    287287                                        assert( false );
    288288                                } // switch
    289                                 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    290                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     289                                varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     290                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    291291                                        Mangler sub_mangler( mangleOverridable, typeMode );
    292292                                        sub_mangler.nextVarNum = nextVarNum;
     
    307307                        mangleName << "V";
    308308                } // if
     309                if ( type->get_mutex() ) {
     310                        mangleName << "M";
     311                } // if
    309312                // Removed due to restrict not affecting function compatibility in GCC
    310313//              if ( type->get_isRestrict() ) {
     
    312315//              } // if
    313316                if ( type->get_lvalue() ) {
     317                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    314318                        mangleName << "L";
    315                 } // if
     319                }
    316320                if ( type->get_atomic() ) {
    317321                        mangleName << "A";
  • src/SymTab/Validate.cc

    raf58ee0 r74bba15  
    5656#include "FixFunction.h"               // for FixFunction
    5757#include "Indexer.h"                   // for Indexer
     58#include "InitTweak/GenInit.h"         // for fixReturnStatements
    5859#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    5960#include "Parser/LinkageSpec.h"        // for C
     
    150151        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    151152        struct ForallPointerDecay final {
    152                 void previsit( ObjectDecl *object );
    153                 void previsit( FunctionDecl *func );
     153                void previsit( ObjectDecl * object );
     154                void previsit( FunctionDecl * func );
    154155        };
    155156
     
    579580
    580581        /// Fix up assertions - flattens assertion lists, removing all trait instances
    581         void forallFixer( Type * func ) {
    582                 for ( TypeDecl * type : func->get_forall() ) {
     582        void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
     583                for ( TypeDecl * type : forall ) {
    583584                        std::list< DeclarationWithType * > asserts;
    584585                        asserts.splice( asserts.end(), type->assertions );
     
    599600                                assertion = assertion->acceptMutator( fixer );
    600601                                if ( fixer.get_isVoid() ) {
    601                                         throw SemanticError( "invalid type void in assertion of function ", func );
     602                                        throw SemanticError( "invalid type void in assertion of function ", node );
    602603                                } // if
    603604                        } // for
     
    607608
    608609        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    609                 forallFixer( object->get_type() );
    610                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
    611                         forallFixer( pointer->get_base() );
     610                forallFixer( object->type->forall, object );
     611                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
     612                        forallFixer( pointer->base->forall, object );
    612613                } // if
    613614                object->fixUniqueId();
     
    615616
    616617        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    617                 forallFixer( func->get_type() );
     618                forallFixer( func->type->forall, func );
    618619                func->fixUniqueId();
    619620        }
  • src/SynTree/BaseSyntaxNode.h

    raf58ee0 r74bba15  
    2626
    2727        virtual void accept( Visitor & v ) = 0;
    28   virtual void print( std::ostream & os, int indent = 0 ) const = 0;
     28        virtual void print( std::ostream & os, int indent = 0 ) const = 0;
    2929};
     30
     31std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node );
    3032
    3133// Local Variables: //
  • src/SynTree/CompoundStmt.cc

    raf58ee0 r74bba15  
    2929
    3030CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
     31}
     32
     33CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement( noLabels ), kids( stmts ) {
    3134}
    3235
  • src/SynTree/Constant.cc

    raf58ee0 r74bba15  
    3232Constant Constant::from_bool( bool b ) {
    3333        return Constant( new BasicType( Type::Qualifiers(), BasicType::Bool ), b ? "1" : "0" , (unsigned long long int)b );
     34}
     35
     36Constant Constant::from_char( char c ) {
     37        return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );
    3438}
    3539
  • src/SynTree/Constant.h

    raf58ee0 r74bba15  
    4040        /// generates a boolean constant of the given bool
    4141        static Constant from_bool( bool b );
     42        /// generates a char constant of the given char
     43        static Constant from_char( char c );
    4244        /// generates an integer constant of the given int
    4345        static Constant from_int( int i );
  • src/SynTree/Declaration.cc

    raf58ee0 r74bba15  
    5959}
    6060
    61 std::ostream & operator<<( std::ostream & out, const Declaration * decl ) {
    62         if ( decl ){
    63                 decl->print( out );
    64         } else {
    65                 out << "nullptr";
    66         }
    67         return out;
    68 }
    69 
    7061
    7162AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) {
  • src/SynTree/Declaration.h

    raf58ee0 r74bba15  
    6262        void fixUniqueId( void );
    6363        virtual Declaration *clone() const = 0;
    64         virtual void accept( Visitor &v ) = 0;
     64        virtual void accept( Visitor &v ) override = 0;
    6565        virtual Declaration *acceptMutator( Mutator &m ) = 0;
    66         virtual void print( std::ostream &os, int indent = 0 ) const = 0;
     66        virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
    6767        virtual void printShort( std::ostream &os, int indent = 0 ) const = 0;
    6868
     
    106106        //void set_functionSpecifiers( Type::FuncSpecifiers newValue ) { fs = newValue; }
    107107
    108         virtual DeclarationWithType *clone() const = 0;
    109         virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
     108        virtual DeclarationWithType *clone() const override = 0;
     109        virtual DeclarationWithType *acceptMutator( Mutator &m )  override = 0;
    110110
    111111        virtual Type * get_type() const = 0;
     
    128128        virtual ~ObjectDecl();
    129129
    130         virtual Type * get_type() const { return type; }
    131         virtual void set_type(Type *newType) { type = newType; }
     130        virtual Type * get_type() const override { return type; }
     131        virtual void set_type(Type *newType) override { type = newType; }
    132132
    133133        Initializer *get_init() const { return init; }
     
    139139        static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init );
    140140
    141         virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); }
    142         virtual void accept( Visitor &v ) { v.visit( this ); }
    143         virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    144         virtual void print( std::ostream &os, int indent = 0 ) const;
    145         virtual void printShort( std::ostream &os, int indent = 0 ) const;
     141        virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
     142        virtual void accept( Visitor &v ) override { v.visit( this ); }
     143        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     144        virtual void print( std::ostream &os, int indent = 0 ) const override;
     145        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    146146};
    147147
     
    157157        virtual ~FunctionDecl();
    158158
    159         Type * get_type() const { return type; }
    160         virtual void set_type(Type * t) { type = strict_dynamic_cast< FunctionType* >( t ); }
     159        virtual Type * get_type() const override { return type; }
     160        virtual void set_type(Type * t) override { type = strict_dynamic_cast< FunctionType* >( t ); }
    161161
    162162        FunctionType * get_functionType() const { return type; }
     
    165165        void set_statements( CompoundStmt *newValue ) { statements = newValue; }
    166166
    167         virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
    168         virtual void accept( Visitor &v ) { v.visit( this ); }
    169         virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    170         virtual void print( std::ostream &os, int indent = 0 ) const;
    171         virtual void printShort( std::ostream &os, int indent = 0 ) const;
     167        virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
     168        virtual void accept( Visitor &v ) override { v.visit( this ); }
     169        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     170        virtual void print( std::ostream &os, int indent = 0 ) const override;
     171        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    172172};
    173173
     
    190190        virtual std::string typeString() const = 0;
    191191
    192         virtual NamedTypeDecl *clone() const = 0;
    193         virtual void print( std::ostream &os, int indent = 0 ) const;
    194         virtual void printShort( std::ostream &os, int indent = 0 ) const;
     192        virtual NamedTypeDecl *clone() const override = 0;
     193        virtual void print( std::ostream &os, int indent = 0 ) const override;
     194        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    195195};
    196196
     
    227227        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    228228
    229         virtual std::string typeString() const;
     229        virtual std::string typeString() const override;
    230230        virtual std::string genTypeString() const;
    231231
    232         virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
    233         virtual void accept( Visitor &v ) { v.visit( this ); }
    234         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    235         virtual void print( std::ostream &os, int indent = 0 ) const;
     232        virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
     233        virtual void accept( Visitor &v ) override { v.visit( this ); }
     234        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     235        virtual void print( std::ostream &os, int indent = 0 ) const override;
    236236
    237237  private:
     
    245245        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    246246
    247         virtual std::string typeString() const;
    248 
    249         virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
    250         virtual void accept( Visitor &v ) { v.visit( this ); }
    251         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     247        virtual std::string typeString() const override;
     248
     249        virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
     250        virtual void accept( Visitor &v ) override { v.visit( this ); }
     251        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    252252  private:
    253253};
     
    274274        AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; }
    275275
    276         virtual void print( std::ostream &os, int indent = 0 ) const;
    277         virtual void printShort( std::ostream &os, int indent = 0 ) const;
     276        virtual void print( std::ostream &os, int indent = 0 ) const override;
     277        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
    278278  protected:
    279279        virtual std::string typeString() const = 0;
     
    290290        bool is_thread() { return kind == DeclarationNode::Thread; }
    291291
    292         virtual StructDecl *clone() const { return new StructDecl( *this ); }
    293         virtual void accept( Visitor &v ) { v.visit( this ); }
    294         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     292        virtual StructDecl *clone() const override { return new StructDecl( *this ); }
     293        virtual void accept( Visitor &v ) override { v.visit( this ); }
     294        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    295295  private:
    296296        DeclarationNode::Aggregate kind;
    297         virtual std::string typeString() const;
     297        virtual std::string typeString() const override;
    298298};
    299299
     
    304304        UnionDecl( const UnionDecl &other ) : Parent( other ) {}
    305305
    306         virtual UnionDecl *clone() const { return new UnionDecl( *this ); }
    307         virtual void accept( Visitor &v ) { v.visit( this ); }
    308         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    309   private:
    310         virtual std::string typeString() const;
     306        virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
     307        virtual void accept( Visitor &v ) override { v.visit( this ); }
     308        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     309  private:
     310        virtual std::string typeString() const override;
    311311};
    312312
     
    317317        EnumDecl( const EnumDecl &other ) : Parent( other ) {}
    318318
    319         virtual EnumDecl *clone() const { return new EnumDecl( *this ); }
    320         virtual void accept( Visitor &v ) { v.visit( this ); }
    321         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    322   private:
    323         virtual std::string typeString() const;
     319        virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
     320        virtual void accept( Visitor &v ) override { v.visit( this ); }
     321        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     322  private:
     323        virtual std::string typeString() const override;
    324324};
    325325
     
    332332        TraitDecl( const TraitDecl &other ) : Parent( other ) {}
    333333
    334         virtual TraitDecl *clone() const { return new TraitDecl( *this ); }
    335         virtual void accept( Visitor &v ) { v.visit( this ); }
    336         virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    337   private:
    338         virtual std::string typeString() const;
     334        virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
     335        virtual void accept( Visitor &v ) override { v.visit( this ); }
     336        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     337  private:
     338        virtual std::string typeString() const override;
    339339};
    340340
     
    350350        void set_stmt( AsmStmt *newValue ) { stmt = newValue; }
    351351
    352         virtual AsmDecl *clone() const { return new AsmDecl( *this ); }
    353         virtual void accept( Visitor &v ) { v.visit( this ); }
    354         virtual AsmDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    355         virtual void print( std::ostream &os, int indent = 0 ) const;
    356         virtual void printShort( std::ostream &os, int indent = 0 ) const;
    357 };
    358 
    359 std::ostream & operator<<( std::ostream & out, const Declaration * decl );
     352        virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
     353        virtual void accept( Visitor &v ) override { v.visit( this ); }
     354        virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     355        virtual void print( std::ostream &os, int indent = 0 ) const override;
     356        virtual void printShort( std::ostream &os, int indent = 0 ) const override;
     357};
     358
    360359std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
    361360
  • src/SynTree/Expression.cc

    raf58ee0 r74bba15  
    741741}
    742742
    743 
    744 std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
    745         if ( expr ) {
    746                 expr->print( out );
    747         } else {
    748                 out << "nullptr";
    749         }
    750         return out;
    751 }
    752 
    753743// Local Variables: //
    754744// tab-width: 4 //
  • src/SynTree/Expression.h

    raf58ee0 r74bba15  
    821821};
    822822
    823 
    824 std::ostream & operator<<( std::ostream & out, const Expression * expr );
    825 
    826823// Local Variables: //
    827824// tab-width: 4 //
  • src/SynTree/Initializer.cc

    raf58ee0 r74bba15  
    137137}
    138138
    139 std::ostream & operator<<( std::ostream & out, const Initializer * init ) {
    140         if ( init ) {
    141                 init->print( out );
    142         } else {
    143                 out << "nullptr";
    144         }
    145         return out;
    146 }
    147 
    148 std::ostream & operator<<( std::ostream & out, const Designation * des ) {
    149         if ( des ) {
    150                 des->print( out );
    151         } else {
    152                 out << "nullptr";
    153         }
    154         return out;
    155 }
    156 
    157139// Local Variables: //
    158140// tab-width: 4 //
  • src/SynTree/Initializer.h

    raf58ee0 r74bba15  
    3838
    3939        virtual Designation * clone() const { return new Designation( *this ); };
    40         virtual void accept( Visitor &v ) { v.visit( this ); }
     40        virtual void accept( Visitor &v ) override { v.visit( this ); }
    4141        virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
    42         virtual void print( std::ostream &os, int indent = 0 ) const;
     42        virtual void print( std::ostream &os, int indent = 0 ) const override;
    4343};
    4444
     
    5555
    5656        virtual Initializer *clone() const = 0;
    57         virtual void accept( Visitor &v ) = 0;
     57        virtual void accept( Visitor &v ) override = 0;
    5858        virtual Initializer *acceptMutator( Mutator &m ) = 0;
    59         virtual void print( std::ostream &os, int indent = 0 ) const = 0;
     59        virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
    6060  private:
    6161        bool maybeConstructed;
     
    7575        void set_value( Expression *newValue ) { value = newValue; }
    7676
    77         virtual SingleInit *clone() const { return new SingleInit( *this); }
    78         virtual void accept( Visitor &v ) { v.visit( this ); }
    79         virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    80         virtual void print( std::ostream &os, int indent = 0 ) const;
     77        virtual SingleInit *clone() const override { return new SingleInit( *this); }
     78        virtual void accept( Visitor &v ) override { v.visit( this ); }
     79        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     80        virtual void print( std::ostream &os, int indent = 0 ) const override;
    8181};
    8282
     
    103103        const_iterator end() const { return initializers.end(); }
    104104
    105         virtual ListInit *clone() const { return new ListInit( *this ); }
    106         virtual void accept( Visitor &v ) { v.visit( this ); }
    107         virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    108         virtual void print( std::ostream &os, int indent = 0 ) const;
     105        virtual ListInit *clone() const override { return new ListInit( *this ); }
     106        virtual void accept( Visitor &v ) override { v.visit( this ); }
     107        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     108        virtual void print( std::ostream &os, int indent = 0 ) const override;
    109109};
    110110
     
    129129        Initializer * get_init() const { return init; }
    130130
    131         ConstructorInit *clone() const { return new ConstructorInit( *this ); }
    132         virtual void accept( Visitor &v ) { v.visit( this ); }
    133         virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    134         virtual void print( std::ostream &os, int indent = 0 ) const;
     131        ConstructorInit *clone() const override { return new ConstructorInit( *this ); }
     132        virtual void accept( Visitor &v ) override { v.visit( this ); }
     133        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     134        virtual void print( std::ostream &os, int indent = 0 ) const override;
    135135
    136136  private:
     
    140140};
    141141
    142 std::ostream & operator<<( std::ostream & out, const Initializer * init );
    143 std::ostream & operator<<( std::ostream & out, const Designation * des );
    144 
    145142// Local Variables: //
    146143// tab-width: 4 //
  • src/SynTree/Statement.cc

    raf58ee0 r74bba15  
    168168}
    169169
    170 SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, std::list<Statement *> &statements ):
     170SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, const std::list<Statement *> &statements ):
    171171        Statement( labels ), condition( condition ), statements( statements ) {
    172172}
     
    196196}
    197197
    198 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
     198CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
    199199        Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) {
    200200        if ( isDefault() && condition != 0 )
     
    497497}
    498498
    499 std::ostream & operator<<( std::ostream & out, const Statement * statement ) {
    500         if ( statement ) {
    501                 statement->print( out );
    502         } else {
    503                 out << "nullptr";
    504         }
    505         return out;
    506 }
    507 
    508499// Local Variables: //
    509500// tab-width: 4 //
  • src/SynTree/Statement.h

    raf58ee0 r74bba15  
    4444
    4545        virtual Statement *clone() const = 0;
    46         virtual void accept( Visitor &v ) = 0;
     46        virtual void accept( Visitor &v ) override = 0;
    4747        virtual Statement *acceptMutator( Mutator &m ) = 0;
    48         virtual void print( std::ostream &os, int indent = 0 ) const;
     48        virtual void print( std::ostream &os, int indent = 0 ) const override;
    4949};
    5050
     
    5454
    5555        CompoundStmt( std::list<Label> labels );
     56        CompoundStmt( std::list<Statement *> stmts );
    5657        CompoundStmt( const CompoundStmt &other );
    5758        virtual ~CompoundStmt();
     
    6162        void push_front( Statement * stmt ) { kids.push_front( stmt ); }
    6263
    63         virtual CompoundStmt *clone() const { return new CompoundStmt( *this ); }
    64         virtual void accept( Visitor &v ) { v.visit( this ); }
    65         virtual CompoundStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    66         virtual void print( std::ostream &os, int indent = 0 ) const;
     64        virtual CompoundStmt *clone() const override { return new CompoundStmt( *this ); }
     65        virtual void accept( Visitor &v ) override { v.visit( this ); }
     66        virtual CompoundStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     67        virtual void print( std::ostream &os, int indent = 0 ) const override;
    6768};
    6869
     
    7273        NullStmt( std::list<Label> labels );
    7374
    74         virtual NullStmt *clone() const { return new NullStmt( *this ); }
    75         virtual void accept( Visitor &v ) { v.visit( this ); }
    76         virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    77         virtual void print( std::ostream &os, int indent = 0 ) const;
     75        virtual NullStmt *clone() const override { return new NullStmt( *this ); }
     76        virtual void accept( Visitor &v ) override { v.visit( this ); }
     77        virtual NullStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     78        virtual void print( std::ostream &os, int indent = 0 ) const override;
    7879};
    7980
     
    8990        void set_expr( Expression *newValue ) { expr = newValue; }
    9091
    91         virtual ExprStmt *clone() const { return new ExprStmt( *this ); }
    92         virtual void accept( Visitor &v ) { v.visit( this ); }
    93         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    94         virtual void print( std::ostream &os, int indent = 0 ) const;
     92        virtual ExprStmt *clone() const override { return new ExprStmt( *this ); }
     93        virtual void accept( Visitor &v ) override { v.visit( this ); }
     94        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     95        virtual void print( std::ostream &os, int indent = 0 ) const override;
    9596};
    9697
     
    146147        void set_elsePart( Statement *newValue ) { elsePart = newValue; }
    147148
    148         virtual IfStmt *clone() const { return new IfStmt( *this ); }
    149         virtual void accept( Visitor &v ) { v.visit( this ); }
    150         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    151         virtual void print( std::ostream &os, int indent = 0 ) const;
     149        virtual IfStmt *clone() const override { return new IfStmt( *this ); }
     150        virtual void accept( Visitor &v ) override { v.visit( this ); }
     151        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     152        virtual void print( std::ostream &os, int indent = 0 ) const override;
    152153};
    153154
     
    157158        std::list<Statement *> statements;
    158159
    159         SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements );
     160        SwitchStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements );
    160161        SwitchStmt( const SwitchStmt &other );
    161162        virtual ~SwitchStmt();
     
    166167        std::list<Statement *> & get_statements() { return statements; }
    167168
    168         virtual void accept( Visitor &v ) { v.visit( this ); }
    169         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    170 
    171         virtual SwitchStmt *clone() const { return new SwitchStmt( *this ); }
    172         virtual void print( std::ostream &os, int indent = 0 ) const;
     169        virtual void accept( Visitor &v ) override { v.visit( this ); }
     170        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     171
     172        virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); }
     173        virtual void print( std::ostream &os, int indent = 0 ) const override;
    173174
    174175};
     
    179180        std::list<Statement *> stmts;
    180181
    181         CaseStmt( std::list<Label> labels, Expression *conditions, std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
     182        CaseStmt( std::list<Label> labels, Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
    182183        CaseStmt( const CaseStmt &other );
    183184        virtual ~CaseStmt();
     
    194195        void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
    195196
    196         virtual void accept( Visitor &v ) { v.visit( this ); }
    197         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    198 
    199         virtual CaseStmt *clone() const { return new CaseStmt( *this ); }
    200         virtual void print( std::ostream &os, int indent = 0 ) const;
     197        virtual void accept( Visitor &v ) override { v.visit( this ); }
     198        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     199
     200        virtual CaseStmt *clone() const override { return new CaseStmt( *this ); }
     201        virtual void print( std::ostream &os, int indent = 0 ) const override;
    201202  private:
    202203        bool _isDefault;
     
    221222        void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
    222223
    223         virtual WhileStmt *clone() const { return new WhileStmt( *this ); }
    224         virtual void accept( Visitor &v ) { v.visit( this ); }
    225         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    226         virtual void print( std::ostream &os, int indent = 0 ) const;
     224        virtual WhileStmt *clone() const override { return new WhileStmt( *this ); }
     225        virtual void accept( Visitor &v ) override { v.visit( this ); }
     226        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     227        virtual void print( std::ostream &os, int indent = 0 ) const override;
    227228};
    228229
     
    247248        void set_body( Statement *newValue ) { body = newValue; }
    248249
    249         virtual ForStmt *clone() const { return new ForStmt( *this ); }
    250         virtual void accept( Visitor &v ) { v.visit( this ); }
    251         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    252         virtual void print( std::ostream &os, int indent = 0 ) const;
     250        virtual ForStmt *clone() const override { return new ForStmt( *this ); }
     251        virtual void accept( Visitor &v ) override { v.visit( this ); }
     252        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     253        virtual void print( std::ostream &os, int indent = 0 ) const override;
    253254};
    254255
     
    276277        const char *get_typename() { return brType[ type ]; }
    277278
    278         virtual BranchStmt *clone() const { return new BranchStmt( *this ); }
    279         virtual void accept( Visitor &v ) { v.visit( this ); }
    280         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    281         virtual void print( std::ostream &os, int indent = 0 ) const;
     279        virtual BranchStmt *clone() const override { return new BranchStmt( *this ); }
     280        virtual void accept( Visitor &v ) override { v.visit( this ); }
     281        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     282        virtual void print( std::ostream &os, int indent = 0 ) const override;
    282283  private:
    283284        static const char *brType[];
     
    295296        void set_expr( Expression *newValue ) { expr = newValue; }
    296297
    297         virtual ReturnStmt *clone() const { return new ReturnStmt( *this ); }
    298         virtual void accept( Visitor &v ) { v.visit( this ); }
    299         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    300         virtual void print( std::ostream &os, int indent = 0 ) const;
     298        virtual ReturnStmt *clone() const override { return new ReturnStmt( *this ); }
     299        virtual void accept( Visitor &v ) override { v.visit( this ); }
     300        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     301        virtual void print( std::ostream &os, int indent = 0 ) const override;
    301302};
    302303
     
    319320        void set_target( Expression * newTarget ) { target = newTarget; }
    320321
    321         virtual ThrowStmt *clone() const { return new ThrowStmt( *this ); }
    322         virtual void accept( Visitor &v ) { v.visit( this ); }
    323         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    324         virtual void print( std::ostream &os, int indent = 0 ) const;
     322        virtual ThrowStmt *clone() const override { return new ThrowStmt( *this ); }
     323        virtual void accept( Visitor &v ) override { v.visit( this ); }
     324        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     325        virtual void print( std::ostream &os, int indent = 0 ) const override;
    325326};
    326327
     
    342343        void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
    343344
    344         virtual TryStmt *clone() const { return new TryStmt( *this ); }
    345         virtual void accept( Visitor &v ) { v.visit( this ); }
    346         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    347         virtual void print( std::ostream &os, int indent = 0 ) const;
     345        virtual TryStmt *clone() const override { return new TryStmt( *this ); }
     346        virtual void accept( Visitor &v ) override { v.visit( this ); }
     347        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     348        virtual void print( std::ostream &os, int indent = 0 ) const override;
    348349};
    349350
     
    370371        void set_body( Statement *newValue ) { body = newValue; }
    371372
    372         virtual CatchStmt *clone() const { return new CatchStmt( *this ); }
    373         virtual void accept( Visitor &v ) { v.visit( this ); }
    374         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    375         virtual void print( std::ostream &os, int indent = 0 ) const;
     373        virtual CatchStmt *clone() const override { return new CatchStmt( *this ); }
     374        virtual void accept( Visitor &v ) override { v.visit( this ); }
     375        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     376        virtual void print( std::ostream &os, int indent = 0 ) const override;
    376377};
    377378
     
    387388        void set_block( CompoundStmt *newValue ) { block = newValue; }
    388389
    389         virtual FinallyStmt *clone() const { return new FinallyStmt( *this ); }
    390         virtual void accept( Visitor &v ) { v.visit( this ); }
    391         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    392         virtual void print( std::ostream &os, int indent = 0 ) const;
     390        virtual FinallyStmt *clone() const override { return new FinallyStmt( *this ); }
     391        virtual void accept( Visitor &v ) override { v.visit( this ); }
     392        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     393        virtual void print( std::ostream &os, int indent = 0 ) const override;
    393394};
    394395
     
    424425        } orelse;
    425426
    426         virtual WaitForStmt *clone() const { return new WaitForStmt( *this ); }
    427         virtual void accept( Visitor &v ) { v.visit( this ); }
    428         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    429         virtual void print( std::ostream &os, int indent = 0 ) const;
     427        virtual WaitForStmt *clone() const override { return new WaitForStmt( *this ); }
     428        virtual void accept( Visitor &v ) override { v.visit( this ); }
     429        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     430        virtual void print( std::ostream &os, int indent = 0 ) const override;
    430431
    431432};
     
    444445        void set_decl( Declaration *newValue ) { decl = newValue; }
    445446
    446         virtual DeclStmt *clone() const { return new DeclStmt( *this ); }
    447         virtual void accept( Visitor &v ) { v.visit( this ); }
    448         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    449         virtual void print( std::ostream &os, int indent = 0 ) const;
     447        virtual DeclStmt *clone() const override { return new DeclStmt( *this ); }
     448        virtual void accept( Visitor &v ) override { v.visit( this ); }
     449        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     450        virtual void print( std::ostream &os, int indent = 0 ) const override;
    450451};
    451452
     
    466467        void set_callStmt( Statement * newValue ) { callStmt = newValue; }
    467468
    468         virtual ImplicitCtorDtorStmt *clone() const { return new ImplicitCtorDtorStmt( *this ); }
    469         virtual void accept( Visitor &v ) { v.visit( this ); }
    470         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    471         virtual void print( std::ostream &os, int indent = 0 ) const;
    472 };
    473 
    474 
    475 std::ostream & operator<<( std::ostream & out, const Statement * statement );
     469        virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); }
     470        virtual void accept( Visitor &v ) override { v.visit( this ); }
     471        virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     472        virtual void print( std::ostream &os, int indent = 0 ) const override;
     473};
    476474
    477475// Local Variables: //
  • src/SynTree/Type.cc

    raf58ee0 r74bba15  
    9999const Type::Qualifiers noQualifiers;
    100100
    101 std::ostream & operator<<( std::ostream & out, const Type * type ) {
    102         if ( type ) {
    103                 type->print( out );
    104         } else {
    105                 out << "nullptr";
    106         } // if
    107         return out;
    108 }
    109 
    110101// Local Variables: //
    111102// tab-width: 4 //
  • src/SynTree/Type.h

    raf58ee0 r74bba15  
    192192        VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    193193
    194         virtual unsigned size() const { return 0; };
    195         virtual bool isComplete() const { return false; }
    196 
    197         virtual VoidType *clone() const { return new VoidType( *this ); }
    198         virtual void accept( Visitor & v ) { v.visit( this ); }
    199         virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
    200         virtual void print( std::ostream & os, int indent = 0 ) const;
     194        virtual unsigned size() const override { return 0; };
     195        virtual bool isComplete() const override { return false; }
     196
     197        virtual VoidType *clone() const override { return new VoidType( *this ); }
     198        virtual void accept( Visitor & v ) override { v.visit( this ); }
     199        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     200        virtual void print( std::ostream & os, int indent = 0 ) const override;
    201201};
    202202
     
    235235        void set_kind( Kind newValue ) { kind = newValue; }
    236236
    237         virtual BasicType *clone() const { return new BasicType( *this ); }
    238         virtual void accept( Visitor & v ) { v.visit( this ); }
    239         virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
    240         virtual void print( std::ostream & os, int indent = 0 ) const;
     237        virtual BasicType *clone() const override { return new BasicType( *this ); }
     238        virtual void accept( Visitor & v ) override { v.visit( this ); }
     239        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     240        virtual void print( std::ostream & os, int indent = 0 ) const override;
    241241
    242242        bool isInteger() const;
     
    268268        bool is_array() const { return isStatic || isVarLen || dimension; }
    269269
    270         virtual bool isComplete() const { return ! isVarLen; }
    271 
    272         virtual PointerType *clone() const { return new PointerType( *this ); }
    273         virtual void accept( Visitor & v ) { v.visit( this ); }
    274         virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
    275         virtual void print( std::ostream & os, int indent = 0 ) const;
     270        virtual bool isComplete() const override { return ! isVarLen; }
     271
     272        virtual PointerType *clone() const override { return new PointerType( *this ); }
     273        virtual void accept( Visitor & v ) override { v.visit( this ); }
     274        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     275        virtual void print( std::ostream & os, int indent = 0 ) const override;
    276276};
    277277