Changes in / [74bba15:af58ee0]


Ignore:
Location:
src
Files:
6 added
12 deleted
59 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r74bba15 raf58ee0  
    443443        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    444444                extension( untypedExpr );
    445                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
     445                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    446446                        OperatorInfo opInfo;
    447                         if ( operatorLookup( nameExpr->name, opInfo ) ) {
    448                                 std::list< Expression* >::iterator arg = untypedExpr->args.begin();
     447                        if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
     448                                std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
    449449                                switch ( opInfo.type ) {
    450450                                  case OT_INDEX:
    451                                         assert( untypedExpr->args.size() == 2 );
     451                                        assert( untypedExpr->get_args().size() == 2 );
    452452                                        (*arg++)->accept( *visitor );
    453453                                        output << "[";
     
    461461                                  case OT_CTOR:
    462462                                  case OT_DTOR:
    463                                         if ( untypedExpr->args.size() == 1 ) {
     463                                        if ( untypedExpr->get_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->args.end() );
     482                                                genCommaList( arg, untypedExpr->get_args().end() );
    483483                                                output << "}) /* " << opInfo.inputName << " */";
    484484                                        } // if
     
    488488                                  case OT_PREFIXASSIGN:
    489489                                  case OT_LABELADDRESS:
    490                                         assert( untypedExpr->args.size() == 1 );
     490                                        assert( untypedExpr->get_args().size() == 1 );
    491491                                        output << "(";
    492492                                        output << opInfo.symbol;
     
    497497                                  case OT_POSTFIX:
    498498                                  case OT_POSTFIXASSIGN:
    499                                         assert( untypedExpr->args.size() == 1 );
     499                                        assert( untypedExpr->get_args().size() == 1 );
    500500                                        (*arg)->accept( *visitor );
    501501                                        output << opInfo.symbol;
     
    504504                                  case OT_INFIX:
    505505                                  case OT_INFIXASSIGN:
    506                                         assert( untypedExpr->args.size() == 2 );
     506                                        assert( untypedExpr->get_args().size() == 2 );
    507507                                        output << "(";
    508508                                        (*arg++)->accept( *visitor );
     
    517517                                } // switch
    518518                        } else {
    519                                 // builtin routines
    520                                 nameExpr->accept( *visitor );
    521                                 output << "(";
    522                                 genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
    523                                 output << ")";
     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
    524530                        } // if
    525531                } else {
    526                         untypedExpr->function->accept( *visitor );
     532                        untypedExpr->get_function()->accept( *visitor );
    527533                        output << "(";
    528                         genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
     534                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    529535                        output << ")";
    530536                } // if
     
    532538
    533539        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
    534                 rangeExpr->low->accept( *visitor );
     540                rangeExpr->get_low()->accept( *visitor );
    535541                output << " ... ";
    536                 rangeExpr->high->accept( *visitor );
     542                rangeExpr->get_high()->accept( *visitor );
    537543        }
    538544
     
    879885
    880886        void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
    881                 updateLocation( caseStmt );
    882                 output << indent;
    883887                if ( caseStmt->isDefault()) {
    884888                        output << "default";
     
    10221026} // namespace CodeGen
    10231027
    1024 std::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 
    10331028// Local Variables: //
    10341029// tab-width: 4 //
  • src/Concurrency/Keywords.cc

    r74bba15 raf58ee0  
    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;
    530531                if( type && type->get_baseStruct()->is_thread() ) {
    531532                        addStartStatement( decl, param );
  • src/Concurrency/Waitfor.cc

    r74bba15 raf58ee0  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "ResolvExpr/Resolver.h"   // for findVoidExpression
     29#include "SymTab/AddVisit.h"       // for acceptAndAdd
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithIndexer {
     114        class GenerateWaitForPass final : public WithStmtsToAdd {
    115115          public:
    116116
     
    126126
    127127                ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
    128                 ObjectDecl * declareFlag( CompoundStmt * stmt );
    129                 Statement  * makeSetter( ObjectDecl * flag );
    130128                ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt );
    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 );
     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();
    135133
    136134                static void implement( std::list< Declaration * > & translationUnit ) {
     
    142140          private:
    143141                FunctionDecl        * decl_waitfor    = nullptr;
    144                 StructDecl          * decl_mask       = nullptr;
    145142                StructDecl          * decl_acceptable = nullptr;
    146143                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;
    147148
    148149                static std::unique_ptr< Type > generic_func;
    149150
     151                UniqueName namer_mon = "__monitors_"s;
    150152                UniqueName namer_acc = "__acceptables_"s;
    151                 UniqueName namer_idx = "__index_"s;
    152                 UniqueName namer_flg = "__do_run_"s;
    153                 UniqueName namer_msk = "__mask_"s;
    154                 UniqueName namer_mon = "__monitors_"s;
    155153                UniqueName namer_tim = "__timeout_"s;
    156154        };
     
    169167        namespace {
    170168                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    171                         return new UntypedExpr(
     169                        return new ApplicationExpr(
    172170                                new NameExpr( "?[?]" ),
    173171                                {
     
    179177
    180178                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    181                         return new UntypedExpr(
     179                        return new ApplicationExpr(
    182180                                        new NameExpr( "?=?" ),
    183181                                        { lhs, rhs }
     
    185183                }
    186184
    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
     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
    197199                                        ),
    198                                         member
    199                                 ),
    200                                 value
    201                         ) );
    202 
    203                         return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
     200                                        value
     201                                )
     202                        );
    204203                }
    205204
     
    209208                        return new ConstantExpr( Constant::from_bool( ifnull ) );
    210209                }
    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                 }
    226210        };
    227211
     
    232216
    233217        void GenerateWaitForPass::premutate( FunctionDecl * decl) {
    234                 if( decl->name != "__waitfor_internal" ) return;
     218                if( decl->name != "__accept_internal" ) return;
    235219
    236220                decl_waitfor = decl;
     
    243227                        assert( !decl_acceptable );
    244228                        decl_acceptable = decl;
    245                 }
    246                 else if( decl->name == "__waitfor_mask_t" ) {
    247                         assert( !decl_mask );
    248                         decl_mask = 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
    249236                }
    250237                else if( decl->name == "monitor_desc" ) {
     
    255242
    256243        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    257                 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", 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 );
    258247
    259248                CompoundStmt * stmt = new CompoundStmt( noLabels );
    260249
    261250                ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
    262                 ObjectDecl * flag        = declareFlag( stmt );
    263                 Statement  * setter      = makeSetter( flag );
    264251
    265252                int index = 0;
    266253                for( auto & clause : waitfor->clauses ) {
    267                         init( acceptables, index, clause, setter, stmt );
     254                        init( acceptables, index, clause, stmt );
    268255
    269256                        index++;
     
    275262                        waitfor->orelse .statement,
    276263                        waitfor->orelse .condition,
    277                         setter,
    278264                        stmt
    279265                );
    280266
    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 );
     267                // Expression * result  = call( acceptables, timeout, orelse, stmt );
     268
     269                // choose( waitfor, result );
    292270
    293271                return stmt;
     
    296274        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    297275        {
    298                 ObjectDecl * acceptables = ObjectDecl::newObject(
     276                ObjectDecl * acceptables = new ObjectDecl(
    299277                        namer_acc.newName(),
     278                        noStorage,
     279                        LinkageSpec::Cforall,
     280                        nullptr,
    300281                        new ArrayType(
    301282                                noQualifiers,
     
    313294                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    314295
    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 
    329296                return acceptables;
    330297        }
    331298
    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 
    362299        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    363300
    364                 ObjectDecl * mon = ObjectDecl::newObject(
     301                ObjectDecl * mon = new ObjectDecl(
    365302                        namer_mon.newName(),
     303                        noStorage,
     304                        LinkageSpec::Cforall,
     305                        nullptr,
    366306                        new ArrayType(
    367307                                noQualifiers,
    368                                 new PointerType(
     308                                new StructInstType(
    369309                                        noQualifiers,
    370                                         new StructInstType(
    371                                                 noQualifiers,
    372                                                 decl_monitor
    373                                         )
     310                                        decl_monitor
    374311                                ),
    375312                                new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ),
     
    379316                        new ListInit(
    380317                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * 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 );
     318                                        return new SingleInit( expr );
    398319                                })
    399320                        )
     
    405326        }
    406327
    407         void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
     328        void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    408329
    409330                ObjectDecl * monitors = declMon( clause, stmt );
    410331
    411                 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
     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 ) ) ) );
    412337
    413338                stmt->push_back( new IfStmt(
    414339                        noLabels,
    415340                        safeCond( clause.condition ),
    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                         }),
     341                        compound,
    423342                        nullptr
    424343                ));
     
    434353                bool has_else,
    435354                Expression *& else_cond,
    436                 Statement * setter,
    437355                CompoundStmt * stmt
    438356        ) {
    439                 ObjectDecl * timeout = ObjectDecl::newObject(
     357                ObjectDecl * timeout = new ObjectDecl(
    440358                        namer_tim.newName(),
     359                        noStorage,
     360                        LinkageSpec::Cforall,
     361                        nullptr,
    441362                        new BasicType(
    442363                                noQualifiers,
     
    453374                        stmt->push_back( new IfStmt(
    454375                                noLabels,
    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                                 }),
     376                                safeCond( else_cond ),
     377                                new ExprStmt(
     378                                        noLabels,
     379                                        makeOpAssign(
     380                                                new VariableExpr( timeout ),
     381                                                time
     382                                        )
     383                                ),
    466384                                nullptr
    467385                        ));
     
    474392                                noLabels,
    475393                                safeCond( else_cond ),
    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                                 }),
     394                                new ExprStmt(
     395                                        noLabels,
     396                                        makeOpAssign(
     397                                                new VariableExpr( timeout ),
     398                                                new ConstantExpr( Constant::from_ulong( 0 ) )
     399                                        )
     400                                ),
    486401                                nullptr
    487402                        ));
     
    490405                }
    491406
    492                 delete setter;
    493 
    494407                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 );
    618408        }
    619409};
  • src/GenPoly/Box.cc

    r74bba15 raf58ee0  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
     34#include "DeclMutator.h"                 // for DeclMutator
    3435#include "FindFunction.h"                // for findFunction, findAndReplace...
    3536#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3839#include "Lvalue.h"                      // for generalizedLvalue
    3940#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
     41#include "PolyMutator.h"                 // for PolyMutator
    4042#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4143#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6062                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6163
    62                 class BoxPass {
    63                 protected:
    64                         BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
    65                         TyVarMap scopeTyVars;
     64                /// Adds layout-generation functions to polymorphic types
     65                class LayoutFunctionBuilder final : public DeclMutator {
     66                        unsigned int functionNesting;  // current level of nested functions
     67                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;
    6674                };
    6775
    68                 /// Adds layout-generation functions to polymorphic types
    69                 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         unsigned int functionNesting = 0;  // current level of nested functions
    71                 public:
    72                         void previsit( FunctionDecl *functionDecl );
    73                         void previsit( StructDecl *structDecl );
    74                         void previsit( UnionDecl *unionDecl );
    75                 };
    76 
    7776                /// 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
    78                 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
     77                class Pass1 final : public PolyMutator {
    7978                  public:
    8079                        Pass1();
    8180
    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();
     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;
    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                 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 );
     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;
    141149
    142150                  private:
     
    150158                /// * Calculates polymorphic offsetof expressions from offset array
    151159                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    152                 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     160                class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    153161                public:
    154162                        PolyGenericCalculator();
     
    189197                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    190198                        UniqueName bufNamer;                           ///< Namer for VLA buffers
     199                        TyVarMap scopeTyVars;
    191200                };
    192201
    193202                /// 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.
    194                 struct Pass3 final : public BoxPass, public WithGuards {
     203                class Pass3 final : public PolyMutator {
     204                  public:
    195205                        template< typename DeclClass >
    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 );
     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:
    206218                };
    207219        } // anonymous namespace
     
    235247
    236248        void box( std::list< Declaration *>& translationUnit ) {
    237                 PassVisitor<LayoutFunctionBuilder> layoutBuilder;
    238                 PassVisitor<Pass1> pass1;
    239                 PassVisitor<Pass2> pass2;
     249                LayoutFunctionBuilder layoutBuilder;
     250                Pass1 pass1;
     251                Pass2 pass2;
    240252                PassVisitor<PolyGenericCalculator> polyCalculator;
    241                 PassVisitor<Pass3> pass3;
    242 
    243                 acceptAll( translationUnit, layoutBuilder );
    244                 mutateAll( translationUnit, pass1 );
    245                 mutateAll( translationUnit, pass2 );
     253                Pass3 pass3;
     254
     255                layoutBuilder.mutateDeclarationList( translationUnit );
     256                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     257                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    246258                mutateAll( translationUnit, polyCalculator );
    247                 mutateAll( translationUnit, pass3 );
     259                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    248260        }
    249261
    250262        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    251263
    252         void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
    253                 visit_children = false;
    254                 maybeAccept( functionDecl->get_functionType(), *visitor );
     264        DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
     265                functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    255266                ++functionNesting;
    256                 maybeAccept( functionDecl->get_statements(), *visitor );
     267                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    257268                --functionNesting;
     269                return functionDecl;
    258270        }
    259271
     
    344356        }
    345357
    346         void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
     358        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    347359                // do not generate layout function for "empty" tag structs
    348                 visit_children = false;
    349                 if ( structDecl->get_members().empty() ) return;
     360                if ( structDecl->get_members().empty() ) return structDecl;
    350361
    351362                // get parameters that can change layout, exiting early if none
    352363                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    353                 if ( otypeParams.empty() ) return;
     364                if ( otypeParams.empty() ) return structDecl;
    354365
    355366                // build layout function signature
     
    402413                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    403414
    404                 declsToAddAfter.push_back( layoutDecl );
     415                addDeclarationAfter( layoutDecl );
     416                return structDecl;
    405417        }
    406418
    407         void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
     419        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    408420                // do not generate layout function for "empty" tag unions
    409                 visit_children = false;
    410                 if ( unionDecl->get_members().empty() ) return;
     421                if ( unionDecl->get_members().empty() ) return unionDecl;
    411422
    412423                // get parameters that can change layout, exiting early if none
    413424                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    414                 if ( otypeParams.empty() ) return;
     425                if ( otypeParams.empty() ) return unionDecl;
    415426
    416427                // build layout function signature
     
    445456                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    446457
    447                 declsToAddAfter.push_back( layoutDecl );
     458                addDeclarationAfter( layoutDecl );
     459                return unionDecl;
    448460        }
    449461
     
    489501                Pass1::Pass1() : tempNamer( "_temp" ) {}
    490502
    491                 void Pass1::premutate( FunctionDecl *functionDecl ) {
     503                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    492504                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    493505                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    494                                 GuardScope( scopeTyVars );
    495                                 GuardValue( retval );
     506                                doBeginScope();
     507                                scopeTyVars.beginScope();
     508
     509                                DeclarationWithType *oldRetval = retval;
    496510
    497511                                // process polymorphic return value
    498512                                retval = nullptr;
    499                                 FunctionType *functionType = functionDecl->type;
    500                                 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
    501                                         retval = functionType->returnVals.front();
     513                                if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
     514                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    502515
    503516                                        // give names to unnamed return values
    504                                         if ( retval->name == "" ) {
    505                                                 retval->name = "_retparm";
    506                                                 retval->linkage = LinkageSpec::C;
     517                                        if ( retval->get_name() == "" ) {
     518                                                retval->set_name( "_retparm" );
     519                                                retval->set_linkage( LinkageSpec::C );
    507520                                        } // if
    508521                                } // if
    509522
    510                                 makeTyVarMap( functionType, scopeTyVars );
    511 
    512                                 std::list< DeclarationWithType *> &paramList = functionType->parameters;
     523                                FunctionType *functionType = functionDecl->get_functionType();
     524                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     525
     526                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    513527                                std::list< FunctionType *> functions;
    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 ) {
     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 ) {
    516530                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    517531                                        } // for
     
    528542                                        } // if
    529543                                } // for
     544
     545                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
     546
     547                                scopeTyVars.endScope();
     548                                retval = oldRetval;
     549                                doEndScope();
    530550                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    531551                        } // if
    532                 }
    533 
    534                 void Pass1::premutate( TypeDecl *typeDecl ) {
     552                        return functionDecl;
     553                }
     554
     555                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    535556                        addToTyVarMap( typeDecl, scopeTyVars );
    536                 }
    537 
    538                 void Pass1::premutate( CommaExpr *commaExpr ) {
     557                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     558                }
     559
     560                Expression *Pass1::mutate( CommaExpr *commaExpr ) {
    539561                        // Attempting to find application expressions that were mutated by the copy constructor passes
    540562                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    552574                                }
    553575                        }
     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
    554588                }
    555589
     
    625659                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    626660                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    627                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     661                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    628662                        return newObj;
    629663                }
     
    741775                                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    742776                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    743                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     777                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    744778                                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    745779                                        assign->get_args().push_back( new VariableExpr( newObj ) );
    746780                                        assign->get_args().push_back( arg );
    747                                         stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
     781                                        stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
    748782                                        arg = new AddressExpr( new VariableExpr( newObj ) );
    749783                                } // if
     
    927961                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    928962                                                adapter = answer.first;
    929                                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
     963                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    930964                                        } // if
    931965                                        assert( adapter != adapters.end() );
     
    10841118                }
    10851119
    1086                 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
     1120                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    10871121                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    10881122                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    10901124                        // }
    10911125                        // std::cerr << "\n";
    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() );
     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() );
    10961132
    10971133                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11461182                }
    11471183
    1148                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
    1149                         if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1150                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     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() ) ) {
    11511187                                        if ( name->get_name() == "*?" ) {
    1152                                                 Expression *ret = expr->args.front();
    1153                                                 expr->args.clear();
     1188                                                Expression *ret = expr->get_args().front();
     1189                                                expr->get_args().clear();
    11541190                                                delete expr;
    1155                                                 return ret;
     1191                                                return ret->acceptMutator( *this );
    11561192                                        } // if
    11571193                                } // if
    11581194                        } // if
    1159                         return expr;
    1160                 }
    1161 
    1162                 void Pass1::premutate( AddressExpr * ) { visit_children = false; }
    1163                 Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
     1195                        return PolyMutator::mutate( expr );
     1196                }
     1197
     1198                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    11641199                        assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
    11651200
     
    11811216                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    11821217                        // out of the if condition.
    1183                         addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
     1218                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    11841219                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    11851220                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    11961231                }
    11971232
    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;
     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() ) );
    12031240                        } // if
    1204                 }
    1205 
    1206                 void Pass1::premutate( PointerType *pointerType ) {
    1207                         GuardScope( scopeTyVars );
     1241                        return returnStmt;
     1242                }
     1243
     1244                Type * Pass1::mutate( PointerType *pointerType ) {
     1245                        scopeTyVars.beginScope();
    12081246                        makeTyVarMap( pointerType, scopeTyVars );
    1209                 }
    1210 
    1211                 void Pass1::premutate( FunctionType *functionType ) {
    1212                         GuardScope( 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();
    12131256                        makeTyVarMap( functionType, scopeTyVars );
    1214                 }
    1215 
    1216                 void Pass1::beginScope() {
     1257
     1258                        Type *ret = Mutator::mutate( functionType );
     1259
     1260                        scopeTyVars.endScope();
     1261                        return ret;
     1262                }
     1263
     1264                void Pass1::doBeginScope() {
    12171265                        adapters.beginScope();
    12181266                }
    12191267
    1220                 void Pass1::endScope() {
     1268                void Pass1::doEndScope() {
    12211269                        adapters.endScope();
    12221270                }
     
    12451293                }
    12461294
    1247                 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
     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 ) );
    12481304                        FunctionType * ftype = functionDecl->get_functionType();
    12491305                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    12691325                }
    12701326
    1271                 void Pass2::premutate( StructDecl * ) {
     1327                ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
     1328                        return handleDecl( objectDecl );
     1329                }
     1330
     1331                template< typename AggDecl >
     1332                AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
    12721333                        // prevent tyVars from leaking into containing scope
    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 ) {
     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 ) {
    12871353                        addToTyVarMap( typeDecl, scopeTyVars );
    1288                 }
    1289 
    1290                 void Pass2::premutate( PointerType *pointerType ) {
    1291                         GuardScope( 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();
    12921367                        makeTyVarMap( pointerType, scopeTyVars );
    1293                 }
    1294 
    1295                 void Pass2::premutate( FunctionType *funcType ) {
    1296                         GuardScope( 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
    12971378                        makeTyVarMap( funcType, scopeTyVars );
    12981379
     
    13331414                                // move all assertions into parameter list
    13341415                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
     1416//      *assert = (*assert)->acceptMutator( *this );
    13351417                                        // assertion parameters may not be used in body, pass along with unused attribute.
    13361418                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    13681450                                                }
    13691451                                        }
     1452
    13701453                                        seenTypes.insert( typeName );
    13711454                                }
     
    13751458                        funcType->get_parameters().splice( last, inferredParams );
    13761459                        addAdapters( funcType );
     1460                        mutateAll( funcType->get_returnVals(), *this );
     1461                        mutateAll( funcType->get_parameters(), *this );
     1462
     1463                        scopeTyVars.endScope();
     1464                        return funcType;
    13771465                }
    13781466
     
    13801468
    13811469                PolyGenericCalculator::PolyGenericCalculator()
    1382                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
     1470                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
    13831471
    13841472                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    17411829
    17421830                template< typename DeclClass >
    1743                 void Pass3::handleDecl( DeclClass * decl, Type * type ) {
    1744                         GuardScope( scopeTyVars );
     1831                DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
     1832                        scopeTyVars.beginScope();
    17451833                        makeTyVarMap( type, scopeTyVars );
     1834
     1835                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1836                        // ScrubTyVars::scrub( decl, scopeTyVars );
    17461837                        ScrubTyVars::scrubAll( decl );
    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 );
     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() );
    17591853                }
    17601854
    17611855                /// Strips the members from a generic aggregate
    1762                 void stripGenericMembers(AggregateDecl * decl) {
    1763                         if ( ! decl->parameters.empty() ) decl->members.clear();
    1764                 }
    1765 
    1766                 void Pass3::premutate( StructDecl * structDecl ) {
     1856                void stripGenericMembers(AggregateDecl* decl) {
     1857                        if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
     1858                }
     1859
     1860                Declaration *Pass3::mutate( StructDecl *structDecl ) {
    17671861                        stripGenericMembers( structDecl );
    1768                 }
    1769 
    1770                 void Pass3::premutate( UnionDecl * unionDecl ) {
     1862                        return structDecl;
     1863                }
     1864
     1865                Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
    17711866                        stripGenericMembers( unionDecl );
    1772                 }
    1773 
    1774                 void Pass3::premutate( TypeDecl * typeDecl ) {
     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
    17751879                        addToTyVarMap( typeDecl, scopeTyVars );
    1776                 }
    1777 
    1778                 void Pass3::premutate( PointerType * pointerType ) {
    1779                         GuardScope( scopeTyVars );
     1880                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     1881                }
     1882
     1883                Type * Pass3::mutate( PointerType *pointerType ) {
     1884                        scopeTyVars.beginScope();
    17801885                        makeTyVarMap( pointerType, scopeTyVars );
    1781                 }
    1782 
    1783                 void Pass3::premutate( FunctionType * functionType ) {
    1784                         GuardScope( 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();
    17851895                        makeTyVarMap( functionType, scopeTyVars );
     1896
     1897                        Type *ret = Mutator::mutate( functionType );
     1898
     1899                        scopeTyVars.endScope();
     1900                        return ret;
    17861901                }
    17871902        } // anonymous namespace
  • src/GenPoly/Specialize.cc

    r74bba15 raf58ee0  
    2222#include <utility>                       // for pair
    2323
    24 #include "Common/PassVisitor.h"
    2524#include "Common/SemanticError.h"        // for SemanticError
    2625#include "Common/UniqueName.h"           // for UniqueName
     
    2928#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    3029#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         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 );
     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 );
    4954
    5055                void handleExplicitParams( ApplicationExpr *appExpr );
     
    199204        }
    200205
    201         struct EnvTrimmer {
     206        struct EnvTrimmer : public Visitor {
    202207                TypeSubstitution * env, * newEnv;
    203208                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    204                 void previsit( TypeDecl * tyDecl ) {
     209                virtual void visit( TypeDecl * tyDecl ) {
    205210                        // transfer known bindings for seen type variables
    206                         if ( Type * t = env->lookup( tyDecl->name ) ) {
    207                                 newEnv->add( tyDecl->name, t );
     211                        if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
     212                                newEnv->add( tyDecl->get_name(), t );
    208213                        }
    209214                }
     
    214219                if ( env ) {
    215220                        TypeSubstitution * newEnv = new TypeSubstitution();
    216                         PassVisitor<EnvTrimmer> trimmer( env, newEnv );
     221                        EnvTrimmer trimmer( env, newEnv );
    217222                        expr->accept( trimmer );
    218223                        return newEnv;
     
    272277                std::string oldParamPrefix = paramPrefix;
    273278                paramPrefix += "p";
    274                 // save stmtsToAddBefore in oldStmts
     279                // save stmtsToAdd in oldStmts
    275280                std::list< Statement* > oldStmts;
    276                 oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
    277                 appExpr->acceptMutator( *visitor );
     281                oldStmts.splice( oldStmts.end(), stmtsToAdd );
     282                mutate( appExpr );
    278283                paramPrefix = oldParamPrefix;
    279284                // write any statements added for recursive specializations into the thunk body
    280                 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
    281                 // restore oldStmts into stmtsToAddBefore
    282                 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
     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 );
    283288
    284289                // add return (or valueless expression) to the thunk
    285290                Statement *appStmt;
    286                 if ( funType->returnVals.empty() ) {
     291                if ( funType->get_returnVals().empty() ) {
    287292                        appStmt = new ExprStmt( noLabels, appExpr );
    288293                } else {
    289294                        appStmt = new ReturnStmt( noLabels, appExpr );
    290295                } // if
    291                 thunkFunc->statements->kids.push_back( appStmt );
     296                thunkFunc->get_statements()->get_kids().push_back( appStmt );
    292297
    293298                // add thunk definition to queue of statements to add
    294                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
     299                stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
    295300                // return address of thunk function as replacement expression
    296301                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    299304        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    300305                // create thunks for the explicit parameters
    301                 assert( appExpr->function->result );
    302                 FunctionType *function = getFunctionType( appExpr->function->result );
     306                assert( appExpr->get_function()->has_result() );
     307                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    303308                assert( function );
    304309                std::list< DeclarationWithType* >::iterator formal;
    305310                std::list< Expression* >::iterator actual;
    306311                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    307                         *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
    308                 }
    309         }
    310 
    311         Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
     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
    312320                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    313321                        // create thunks for the inferred parameters
     
    323331        }
    324332
    325         Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
    326                 assert( addrExpr->result );
    327                 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
     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() ) );
    328337                return addrExpr;
    329338        }
    330339
    331         Expression * Specialize::postmutate( CastExpr *castExpr ) {
    332                 if ( castExpr->result->isVoid() ) {
     340        Expression * Specialize::mutate( CastExpr *castExpr ) {
     341                castExpr->get_arg()->acceptMutator( *this );
     342                if ( castExpr->get_result()->isVoid() ) {
    333343                        // can't specialize if we don't have a return value
    334344                        return castExpr;
    335345                }
    336                 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
    337                 if ( specialized != castExpr->arg ) {
     346                Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
     347                if ( specialized != castExpr->get_arg() ) {
    338348                        // assume here that the specialization incorporates the cast
    339349                        return specialized;
     
    343353        }
    344354
     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
    345371        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    346                 PassVisitor<Specialize> spec;
     372                Specialize spec;
    347373                mutateAll( translationUnit, spec );
    348374        }
  • src/GenPoly/module.mk

    r74bba15 raf58ee0  
    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 \
    1920       GenPoly/ScrubTyVars.cc \
    2021       GenPoly/Lvalue.cc \
     
    2223       GenPoly/CopyParams.cc \
    2324       GenPoly/FindFunction.cc \
     25       GenPoly/DeclMutator.cc \
    2426       GenPoly/InstantiateGeneric.cc
  • src/InitTweak/FixInit.cc

    r74bba15 raf58ee0  
    3636#include "FixGlobalInit.h"             // for fixGlobalInit
    3737#include "GenInit.h"                   // for genCtorDtor
     38#include "GenPoly/DeclMutator.h"       // for DeclMutator
    3839#include "GenPoly/GenPoly.h"           // for getFunctionType
     40#include "GenPoly/PolyMutator.h"       // for PolyMutator
    3941#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4042#include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
     
    4446#include "SymTab/Indexer.h"            // for Indexer
    4547#include "SymTab/Mangler.h"            // for Mangler
     48#include "SynTree/AddStmtVisitor.h"    // for AddStmtVisitor
    4649#include "SynTree/Attribute.h"         // for Attribute
    4750#include "SynTree/Constant.h"          // for Constant
     
    5558#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    5659#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
     60#include "Tuples/Tuples.h"             // for isTtype
    5761
    5862bool ctordtorp = false; // print all debug
     
    183187                };
    184188
    185                 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
     189                class FixCopyCtors final : public GenPoly::PolyMutator {
    186190                  public:
    187191                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
     
    190194                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    191195
    192                         Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
    193                         void premutate( StmtExpr * stmtExpr );
    194                         void premutate( UniqueExpr * unqExpr );
     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;
    195201
    196202                        UnqCount & unqCount;
     
    237243                };
    238244
    239                 struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer {
     245                class FixCtorExprs final : public GenPoly::DeclMutator {
     246                  public:
    240247                        /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
    241248                        static void fix( std::list< Declaration * > & translationUnit );
    242249
    243                         Expression * postmutate( ConstructorExpr * ctorExpr );
     250                        using GenPoly::DeclMutator::mutate;
     251                        virtual Expression * mutate( ConstructorExpr * ctorExpr ) override;
    244252                };
    245253        } // namespace
     
    308316
    309317                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    310                         PassVisitor<FixCopyCtors> fixer( unqCount );
     318                        FixCopyCtors fixer( unqCount );
    311319                        mutateAll( translationUnit, fixer );
    312320                }
     
    318326
    319327                void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
    320                         PassVisitor<FixCtorExprs> fixer;
    321                         mutateAll( translationUnit, fixer );
     328                        FixCtorExprs fixer;
     329                        fixer.mutateDeclarationList( translationUnit );
    322330                }
    323331
     
    331339                                } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    332340                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    333                                         assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
     341                                        assert( ftype );
    334342                                        if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
    335343                                                Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
     
    360368                }
    361369
    362                 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); }
     370                bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
     371                        return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
     372                }
    363373
    364374                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     
    397407                        result = result->clone();
    398408                        env->apply( result );
    399                         ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
     409                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    400410                        tmp->get_type()->set_const( false );
    401411
     
    411421                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    412422                        }
    413 
    414                         // set a unique name for the temporary once it's certain the call is necessary
    415                         tmp->name = tempNamer.newName();
    416423
    417424                        // replace argument to function call with temporary
     
    443450                                result = result->clone();
    444451                                env->apply( result );
    445                                 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
     452                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    446453                                ret->get_type()->set_const( false );
    447454                                impCpCtorExpr->get_returnDecls().push_back( ret );
    448455                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    449456                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
    450                                         // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
     457                                        // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    451458                                        destructRet( ret, impCpCtorExpr );
    452459                                }
     
    465472                                result = result->clone();
    466473                                env->apply( result );
    467                                 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
     474                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    468475                                ret->get_type()->set_const( false );
    469476                                stmtExpr->get_returnDecls().push_front( ret );
     
    502509                        } else {
    503510                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    504                                 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), nullptr ) );
     511                                unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
    505512                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    506513                        }
     
    508515                }
    509516
    510                 Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     517                Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    511518                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    512519
     520                        impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    513521                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    514522                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    517525                        // add all temporary declarations and their constructors
    518526                        for ( ObjectDecl * obj : tempDecls ) {
    519                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     527                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    520528                        } // for
    521529                        for ( ObjectDecl * obj : returnDecls ) {
    522                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     530                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    523531                        } // for
    524532
     
    528536                        } // for
    529537
     538                        // xxx - update to work with multiple return values
    530539                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    531540                        Expression * callExpr = impCpCtorExpr->get_callExpr();
     
    560569                }
    561570
    562                 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
     571                Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
    563572                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    564573                        // since temporaries can be shared across sub-expressions, e.g.
    565574                        //   [A, A] f();
    566575                        //   g([A] x, [A] y);
    567                         //   g(f());
     576                        //   f(g());
    568577                        // 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;
    572578                        std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    573579                        for ( Statement *& stmt : stmts ) {
    574                                 stmt = stmt->acceptMutator( *visitor );
     580                                stmt = stmt->acceptMutator( *this );
    575581                        } // for
     582                        // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    576583                        assert( stmtExpr->get_result() );
    577584                        Type * result = stmtExpr->get_result();
    578585                        if ( ! result->isVoid() ) {
    579586                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    580                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     587                                        stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    581588                                } // for
    582589                                // add destructors after current statement
     
    585592                                } // for
    586593                                // must have a non-empty body, otherwise it wouldn't have a result
    587                                 assert( ! stmts.empty() );
     594                                CompoundStmt * body = stmtExpr->get_statements();
     595                                assert( ! body->get_kids().empty() );
    588596                                assert( ! stmtExpr->get_returnDecls().empty() );
    589                                 stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
     597                                body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    590598                                stmtExpr->get_returnDecls().clear();
    591599                                stmtExpr->get_dtors().clear();
     
    593601                        assert( stmtExpr->get_returnDecls().empty() );
    594602                        assert( stmtExpr->get_dtors().empty() );
    595                 }
    596 
    597                 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {
    598                         visit_children = false;
     603                        return stmtExpr;
     604                }
     605
     606                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
    599607                        unqCount[ unqExpr->get_id() ]--;
    600608                        static std::unordered_map< int, std::list< Statement * > > dtors;
    601609                        static std::unordered_map< int, UniqueExpr * > unqMap;
     610                        static std::unordered_set< int > addDeref;
    602611                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    603612                        if ( unqMap.count( unqExpr->get_id() ) ) {
     
    610619                                        stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    611620                                }
    612                                 return;
    613                         }
    614                         PassVisitor<FixCopyCtors> fixer( unqCount );
     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 );
    615628                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    616                         stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
     629                        stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
    617630                        unqMap[unqExpr->get_id()] = unqExpr;
    618631                        if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    619632                                stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    620633                        } else { // remember dtors for last instance of unique expr
    621                                 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter;
    622                         }
    623                         return;
     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;
    624647                }
    625648
     
    796819                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    797820                                        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
    800821                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    801                                                 // set dtor location to the object's location for error messages
    802                                                 ctorInit->dtor->location = objDecl->location;
     822                                                // don't need to call intrinsic dtor, because it does nothing, but
     823                                                // non-intrinsic dtors must be called
    803824                                                reverseDeclOrder.front().push_front( objDecl );
    804825                                        } // if
     
    9911012                                        // skip non-DWT members
    9921013                                        if ( ! field ) continue;
    993                                         // skip non-constructable members
    994                                         if ( ! tryConstruct( field ) ) continue;
    9951014                                        // skip handled members
    9961015                                        if ( ! unhandled.count( field ) ) continue;
     
    11231142                }
    11241143
    1125                 Expression * FixCtorExprs::postmutate( ConstructorExpr * ctorExpr ) {
     1144                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    11261145                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    11271146                        // xxx - is the size check necessary?
     
    11291148
    11301149                        // 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.
    1131                         ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
    1132                         declsToAddBefore.push_back( tmp );
     1150                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
     1151                        addDeclaration( tmp );
    11331152
    11341153                        // xxx - this can be TupleAssignExpr now. Need to properly handle this case.
     
    11391158                        delete ctorExpr;
    11401159
    1141                         // build assignment and replace constructor's first argument with new temporary
    11421160                        Expression *& firstArg = callExpr->get_args().front();
    1143                         Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } );
     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 );
    11441181                        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;
    11511182
    11521183                        // for constructor expr:
     
    11571188                        //   T & tmp;
    11581189                        //   &tmp = &x, ?{}(tmp), tmp
    1159                         CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1190                        CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11601191                        commaExpr->set_env( env );
    11611192                        return commaExpr;
  • src/InitTweak/GenInit.cc

    r74bba15 raf58ee0  
    2626#include "Common/UniqueName.h"     // for UniqueName
    2727#include "Common/utility.h"        // for ValueGuard, maybeClone
     28#include "GenPoly/DeclMutator.h"   // for DeclMutator
    2829#include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
    2930#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
     
    6162        };
    6263
    63         struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
     64        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6465                /// create constructor and destructor statements for object declarations.
    6566                /// the actual call statements will be added in after the resolver has run
     
    7475                // that need to be constructed or destructed
    7576                void previsit( StructDecl *aggregateDecl );
    76                 void previsit( AggregateDecl * ) { visit_children = false; }
    77                 void previsit( NamedTypeDecl * ) { visit_children = false; }
    78                 void previsit( FunctionType * ) { visit_children = false; }
     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; }
    7983
    8084                void previsit( CompoundStmt * compoundStmt );
     
    9296        };
    9397
    94         struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
     98        class HoistArrayDimension final : public GenPoly::DeclMutator {
     99          public:
     100                typedef GenPoly::DeclMutator Parent;
     101
    95102                /// hoist dimension from array types in object declaration so that it uses a single
    96103                /// const variable of type size_t, so that side effecting array dimensions are only
     
    98105                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    99106
    100                 void premutate( ObjectDecl * objectDecl );
    101                 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
    102                 void premutate( FunctionDecl *functionDecl );
     107          private:
     108                using Parent::mutate;
     109
     110                virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
     111                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
    103112                // should not traverse into any of these declarations to find objects
    104113                // that need to be constructed or destructed
    105                 void premutate( AggregateDecl * ) { visit_children = false; }
    106                 void premutate( NamedTypeDecl * ) { visit_children = false; }
    107                 void premutate( FunctionType * ) { visit_children = false; }
     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; }
    108122
    109123                void hoist( Type * type );
     
    114128
    115129        void genInit( std::list< Declaration * > & translationUnit ) {
    116                 fixReturnStatements( translationUnit );
     130                ReturnFixer::makeReturnTemp( translationUnit );
    117131                HoistArrayDimension::hoistArrayDimension( translationUnit );
    118132                CtorDtor::generateCtorDtor( translationUnit );
    119133        }
    120134
    121         void fixReturnStatements( std::list< Declaration * > & translationUnit ) {
     135        void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
    122136                PassVisitor<ReturnFixer> fixer;
    123137                mutateAll( translationUnit, fixer );
     
    129143                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    130144                // is being returned
    131                 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
     145                if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
    132146                        // explicitly construct the return value using the return expression and the retVal object
    133147                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    144158                GuardValue( funcName );
    145159
    146                 ftype = functionDecl->type;
    147                 funcName = functionDecl->name;
     160                ftype = functionDecl->get_functionType();
     161                funcName = functionDecl->get_name();
    148162        }
    149163
     
    151165        // which would be incorrect if it is a side-effecting computation.
    152166        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    153                 PassVisitor<HoistArrayDimension> hoister;
    154                 mutateAll( translationUnit, hoister );
    155         }
    156 
    157         void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
    158                 GuardValue( storageClasses );
     167                HoistArrayDimension hoister;
     168                hoister.mutateDeclarationList( translationUnit );
     169        }
     170
     171        DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
    159172                storageClasses = objectDecl->get_storageClasses();
    160         }
    161 
    162         DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
     173                DeclarationWithType * temp = Parent::mutate( objectDecl );
    163174                hoist( objectDecl->get_type() );
    164                 return objectDecl;
     175                return temp;
    165176        }
    166177
     
    183194
    184195                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    185                         declsToAddBefore.push_back( arrayDimension );
     196                        addDeclaration( arrayDimension );
    186197
    187198                        hoist( arrayType->get_base() );
     
    190201        }
    191202
    192         void HoistArrayDimension::premutate( FunctionDecl * ) {
    193                 GuardValue( inFunction );
     203        DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
     204                ValueGuard< bool > oldInFunc( inFunction );
     205                inFunction = true;
     206                DeclarationWithType * decl = Parent::mutate( functionDecl );
     207                return decl;
    194208        }
    195209
     
    200214
    201215        bool CtorDtor::isManaged( Type * type ) const {
    202                 // references are never constructed
     216                // at least for now, references are never constructed
    203217                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
    204218                // need to clear and reset qualifiers when determining if a type is managed
     
    207221                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    208222                        // tuple is also managed if any of its components are managed
    209                         if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
     223                        if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
    210224                                return true;
    211225                        }
     
    291305
    292306        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
    293                 visit_children = false;  // do not try and construct parameters or forall parameters
    294307                GuardValue( inFunction );
    295308                inFunction = true;
     
    305318                }
    306319
    307                 maybeAccept( functionDecl->get_statements(), *visitor );
     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
    308324        }
    309325
     
    324340        }
    325341
    326         void CtorDtor::previsit( CompoundStmt * ) {
     342        void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
    327343                GuardScope( managedTypes );
    328344        }
  • src/InitTweak/GenInit.h

    r74bba15 raf58ee0  
    2525        void genInit( std::list< Declaration * > & translationUnit );
    2626
    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 );
     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 );
    3229
    3330        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/InitTweak/InitTweak.cc

    r74bba15 raf58ee0  
     1#include <stddef.h>                // for NULL
    12#include <algorithm>               // for find, all_of
    23#include <cassert>                 // for assertf, assert, strict_dynamic_cast
     
    2223#include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
    2324#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 ), nullptr );
     186                        *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
    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 nullptr;
     252                if ( ! init ) return NULL;
    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 nullptr;
     257                        return NULL;
    258258                } else {
    259                         init = nullptr; // init was consumed in creating the list init
     259                        init = NULL; // init was consumed in creating the list init
    260260                        return block;
    261261                }
    262262        }
    263263
    264         Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
    265                 return nullptr;
     264        Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) {
     265                return NULL;
    266266        }
    267267
     
    270270        }
    271271
    272         bool tryConstruct( DeclarationWithType * dwt ) {
    273                 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
    274                 if ( ! objDecl ) return false;
     272        bool tryConstruct( ObjectDecl * objDecl ) {
    275273                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    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 );
     274                        (objDecl->get_init() == NULL ||
     275                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
     276                        && ! objDecl->get_storageClasses().is_extern;
    284277        }
    285278
     
    321314                collectCtorDtorCalls( stmt, matches );
    322315                assert( matches.size() <= 1 );
    323                 return matches.size() == 1 ? matches.front() : nullptr;
     316                return matches.size() == 1 ? matches.front() : NULL;
    324317        }
    325318
     
    366359        ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
    367360                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
    368                 if ( ! appExpr ) return nullptr;
     361                if ( ! appExpr ) return NULL;
    369362                DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
    370363                assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
    371364                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    372365                // will call all member dtors, and some members may have a user defined dtor.
    373                 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;
     366                return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
    374367        }
    375368
     
    489482                        return refType->get_base();
    490483                } else {
    491                         return nullptr;
     484                        return NULL;
    492485                }
    493486        }
     
    495488        Type * isPointerType( Type * type ) {
    496489                if ( getPointerBase( type ) ) return type;
    497                 else return nullptr;
     490                else return NULL;
    498491        }
    499492
  • src/InitTweak/InitTweak.h

    r74bba15 raf58ee0  
    3333        std::list< Expression * > makeInitList( Initializer * init );
    3434
    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 );
     35        /// True if the resolver should try to construct objDecl
     36        bool tryConstruct( ObjectDecl * objDecl );
    4037
    4138        /// True if the Initializer contains designations
  • src/Makefile.in

    r74bba15 raf58ee0  
    172172        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    173173        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
     174        GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) \
    174175        GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \
    175176        GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
     
    177178        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    178179        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
     180        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    179181        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    180182        InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
     
    251253        SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
    252254        SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
     255        SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT) \
    253256        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    254257        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
     
    494497        ControlStruct/ForExprMutator.cc \
    495498        ControlStruct/ExceptTranslate.cc GenPoly/Box.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 \
     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 \
    499503        InitTweak/GenInit.cc InitTweak/FixInit.cc \
    500504        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
     
    531535        SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    532536        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.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
     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
    537541MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    538542        ${cfa_cpplib_PROGRAMS}}
     
    713717GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
    714718        GenPoly/$(DEPDIR)/$(am__dirstamp)
     719GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
     720        GenPoly/$(DEPDIR)/$(am__dirstamp)
    715721GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
    716722        GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    723729GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
    724730        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     731GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
     732        GenPoly/$(DEPDIR)/$(am__dirstamp)
    725733GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    726734        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    921929SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
    922930        SynTree/$(DEPDIR)/$(am__dirstamp)
     931SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT):  \
     932        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    923933SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    924934        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
     
    9981008@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@
    9991009@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@
    10001011@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    10011012@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
    10021013@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    10031014@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@
    10041016@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    10051017@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     
    10441056@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@
    10451057@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@
    10461059@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
    10471060@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@
     
    14371450@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`
    14381451
     1452GenPoly/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
     1459GenPoly/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
    14391466GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc
    14401467@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
     
    15071534@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`
    15081535
     1536GenPoly/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
     1543GenPoly/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
    15091550GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    15101551@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
     
    25422583@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    25432584@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
     2586SynTree/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
     2593SynTree/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`
    25442599
    25452600SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
  • src/Parser/StatementNode.cc

    r74bba15 raf58ee0  
    234234                target,
    235235                maybeMoveBuild<Statement >( stmt ),
    236                 notZeroExpr( maybeMoveBuild<Expression>( when ) )
     236                maybeMoveBuild<Expression>( when )
    237237        });
    238238
     
    250250        delete targetExpr;
    251251
    252         node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{
     252        node->clauses.push_back( WaitForStmt::Clause{
    253253                std::move( target ),
    254254                maybeMoveBuild<Statement >( stmt ),
    255                 notZeroExpr( maybeMoveBuild<Expression>( when ) )
     255                maybeMoveBuild<Expression>( when )
    256256        });
    257257
     
    265265                node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    266266                node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    267                 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
     267                node->timeout.condition = maybeMoveBuild<Expression>( when    );
    268268        }
    269269        else {
    270                 node->orelse.statement  = maybeMoveBuild<Statement >( stmt );
    271                 node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( when ) );
     270                node->orelse.statement  = maybeMoveBuild<Statement >( stmt    );
     271                node->orelse.condition  = maybeMoveBuild<Expression>( when    );
    272272        }
    273273
     
    280280        node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    281281        node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    282         node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
     282        node->timeout.condition = maybeMoveBuild<Expression>( when    );
    283283
    284284        node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
    285         node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
     285        node->orelse.condition = 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// }
    289295
    290296Statement *build_compound( StatementNode *first ) {
  • src/Parser/parserutility.cc

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

    r74bba15 raf58ee0  
    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                }
    146153        } // 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

    r74bba15 raf58ee0  
    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 );
    5752          private:
    5853                virtual void visit( ApplicationExpr *applicationExpr );
     
    8681                virtual void visit( StmtExpr *stmtExpr );
    8782                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 );
    8887
    8988                /// Adds alternatives for anonymous members
     
    109108
    110109        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
    111         void referenceToRvalueConversion( Expression *& expr );
    112110
    113111        template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/Resolver.cc

    r74bba15 raf58ee0  
    4040#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4141#include "typeops.h"                     // for extractResultType
    42 #include "Unify.h"                       // for unify
    4342
    4443using namespace std;
     
    7271                void previsit( ThrowStmt *throwStmt );
    7372                void previsit( CatchStmt *catchStmt );
    74                 void previsit( WaitForStmt * stmt );
    7573
    7674                void previsit( SingleInit *singleInit );
     
    9593                PassVisitor<Resolver> resolver;
    9694                acceptAll( translationUnit, resolver );
    97         }
    98 
    99         void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
    100                 PassVisitor<Resolver> resolver( indexer );
    101                 maybeAccept( decl, resolver );
    10295        }
    10396
     
    123116        }
    124117
    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 
    146118        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
    147140                bool isIntegralType( Type *type ) {
    148141                        if ( dynamic_cast< EnumInstType * >( type ) ) {
     
    398391        }
    399392
    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 
    603393        template< typename T >
    604394        bool isCharType( T t ) {
  • src/ResolvExpr/Resolver.h

    r74bba15 raf58ee0  
    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 );
    3231        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    3332        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
    34         Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );
    3533        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3634        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r74bba15 raf58ee0  
    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::cerr << "adding " << *theVar;
     125///       std::cout << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cerr << " bound to ";
    128 ///         theClass->type->print( std::cerr );
    129 ///         std::cerr << std::endl;
     127///         std::cout << " bound to ";
     128///         theClass->type->print( std::cout );
     129///         std::cout << 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::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
  • src/SymTab/Autogen.cc

    r74bba15 raf58ee0  
    1616#include "Autogen.h"
    1717
     18#include <cstddef>                 // for NULL
    1819#include <algorithm>               // for count_if
    1920#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2627#include "AddVisit.h"              // for addVisit
    2728#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
    3132#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
    32 #include "InitTweak/GenInit.h"     // for fixReturnStatements
    33 #include "ResolvExpr/Resolver.h"   // for resolveDecl
    3433#include "SymTab/Mangler.h"        // for Mangler
    3534#include "SynTree/Attribute.h"     // For Attribute
     
    5453        };
    5554
    56         struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
     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
    5766                AutogenerateRoutines();
    5867
    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 );
     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 );
    7080
    7181          private:
    72                 GenPoly::ScopedSet< std::string > structsDone;
     82                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     83
     84                std::list< Declaration * > declsToAdd, declsToAddAfter;
     85                std::set< std::string > structsDone;
    7386                unsigned int functionNesting = 0;     // current level of nested functions
    7487                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    8093
    8194        /// generates routines for tuple types.
    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 );
     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 );
    88107
    89108          private:
     
    93112
    94113        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    95                 PassVisitor<AutogenerateRoutines> generator;
    96                 acceptAll( translationUnit, generator );
     114                AutogenerateRoutines generator;
     115                acceptAndAdd( translationUnit, generator );
    97116
    98117                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
    99118                // AutogenTupleRoutines tupleGenerator;
    100                 // acceptAll( translationUnit, tupleGenerator );
     119                // tupleGenerator.mutateDeclarationList( translationUnit );
    101120        }
    102121
    103122        bool isUnnamedBitfield( ObjectDecl * obj ) {
    104                 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
     123                return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
    105124        }
    106125
     
    109128                FunctionDecl * decl = functionDecl->clone();
    110129                delete decl->get_statements();
    111                 decl->set_statements( nullptr );
     130                decl->set_statements( NULL );
    112131                declsToAdd.push_back( decl );
    113132                decl->fixUniqueId();
     
    320339                                assert( ! func->get_functionType()->get_parameters().empty() );
    321340                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    322                                 ObjectDecl * srcParam = nullptr;
     341                                ObjectDecl * srcParam = NULL;
    323342                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    324343                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    327346                                assert( dstParam );
    328347
    329                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
     348                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    330349                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    331350                        } // if
     
    366385                                } else {
    367386                                        // no matching parameter, initialize field with default ctor
    368                                         makeStructMemberOp( dstParam, nullptr, field, func );
     387                                        makeStructMemberOp( dstParam, NULL, field, func );
    369388                                }
    370389                        }
     
    382401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    383402                // Builtins do not use autogeneration.
    384                 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
     403                if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
     404                         aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
    385405                        return;
    386406                }
    387407
    388408                // Make function polymorphic in same parameters as generic struct, if applicable
    389                 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     409                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    390410
    391411                // generate each of the functions based on the supplied FuncData objects
     
    552572                // the order here determines the order that these functions are generated.
    553573                // assignment should come last since it uses copy constructor in return.
    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;
     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 ) {
    562581                if ( ! enumDecl->get_members().empty() ) {
    563582                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    567586        }
    568587
    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 ) {
     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() ) {
    574592                                // need to visit assertions so that they are added to the appropriate maps
    575                                 acceptAll( typeDecl->assertions, *visitor );
    576                                 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
     593                                acceptAll( typeDecl->get_assertions(), *this );
     594                                structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
    577595                        }
    578596                        structInst.set_baseStruct( structDecl );
    579597                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    580                         structsDone.insert( structDecl->name );
     598                        structsDone.insert( structDecl->get_name() );
    581599                } // if
    582600        }
    583601
    584         void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
    585                 visit_children = false;
     602        void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    586603                if ( ! unionDecl->get_members().empty() ) {
    587604                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    602619
    603620        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    604         void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
    605                 visit_children = false;
     621        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    606622                if ( ! typeDecl->base ) return;
    607623
     
    648664        }
    649665
    650         void AutogenerateRoutines::previsit( FunctionType *) {
     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 *) {
    651674                // ensure that we don't add assignment ops for types defined as part of the function
    652                 visit_children = false;
    653         }
    654 
    655         void AutogenerateRoutines::previsit( PointerType *) {
     675        }
     676
     677        void AutogenerateRoutines::visit( PointerType *) {
    656678                // ensure that we don't add assignment ops for types defined as part of the pointer
    657                 visit_children = false;
    658         }
    659 
    660         void AutogenerateRoutines::previsit( TraitDecl * ) {
     679        }
     680
     681        void AutogenerateRoutines::visit( TraitDecl *) {
    661682                // ensure that we don't add assignment ops for types defined as part of the trait
    662                 visit_children = false;
    663         }
    664 
    665         void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
    666                 visit_children = false;
     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 ) {
    667693                // record the existence of this function as appropriate
    668694                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    671697                insert( functionDecl, destructable, InitTweak::isDestructor );
    672698
    673                 maybeAccept( functionDecl->type, *visitor );
     699                maybeAccept( functionDecl->get_functionType(), *this );
    674700                functionNesting += 1;
    675                 maybeAccept( functionDecl->statements, *visitor );
     701                maybeAccept( functionDecl->get_statements(), *this );
    676702                functionNesting -= 1;
    677703        }
    678704
    679         void AutogenerateRoutines::previsit( CompoundStmt * ) {
    680                 GuardScope( constructable );
    681                 GuardScope( assignable );
    682                 GuardScope( copyable );
    683                 GuardScope( destructable );
    684                 GuardScope( structsDone );
     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 );
    685719        }
    686720
     
    700734        }
    701735
    702         void AutogenTupleRoutines::postvisit( TupleType * tupleType ) {
     736        Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
     737                tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
    703738                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
    704                 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return;
     739                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
    705740                seenTuples.insert( mangleName );
    706741
     
    750785                makeTupleFunctionBody( dtorDecl );
    751786
    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 );
     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 ) );
    761797                functionNesting += 1;
    762                 maybeAccept( functionDecl->statements, *visitor );
     798                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    763799                functionNesting -= 1;
    764         }
    765 
    766         void AutogenTupleRoutines::previsit( CompoundStmt * ) {
    767                 GuardScope( seenTuples );
     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;
    768808        }
    769809} // SymTab
  • src/SymTab/FixFunction.cc

    r74bba15 raf58ee0  
    2727
    2828        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
    29                 // can't delete function type because it may contain assertions, so transfer ownership to new object
    3029                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() );
    3130                functionDecl->get_attributes().clear();
    32                 functionDecl->type = nullptr;
     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() );
    3333                delete functionDecl;
    3434                return pointer;
  • src/SymTab/Indexer.cc

    r74bba15 raf58ee0  
    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
    4255        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    4356        typedef std::unordered_map< std::string, MangleTable > IdTable;
     
    185198        }
    186199
    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 ) {
     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 ) {
    192205                that.tables = 0;
    193206        }
  • src/SymTab/Indexer.h

    r74bba15 raf58ee0  
    2626        class Indexer {
    2727          public:
    28                 explicit Indexer();
     28                explicit Indexer( bool useDebug = false );
    2929
    3030                Indexer( const Indexer &that );
     
    7676                void addTrait( TraitDecl *decl );
    7777
    78                 bool doDebug = false; ///< Display debugging trace?
    7978          private:
    8079                struct Impl;
     
    8281                Impl *tables;         ///< Copy-on-write instance of table data structure
    8382                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

    r74bba15 raf58ee0  
    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->types, *this );
     236                acceptAll( tupleType->get_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( ZeroType * ) {
     245        void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
    246246                mangleName << "Z";
    247247        }
    248248
    249         void Mangler::visit( OneType * ) {
     249        void Mangler::visit( __attribute__((unused)) OneType *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->name.length() + 1 ) << decl->name;
     255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_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->forall.begin(); i != type->forall.end(); ++i ) {
     272                        for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    273273                                switch ( (*i)->get_kind() ) {
    274274                                  case TypeDecl::Any:
     
    287287                                        assert( false );
    288288                                } // switch
    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 ) {
     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 ) {
    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
    312309                // Removed due to restrict not affecting function compatibility in GCC
    313310//              if ( type->get_isRestrict() ) {
     
    315312//              } // if
    316313                if ( type->get_lvalue() ) {
    317                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    318314                        mangleName << "L";
    319                 }
     315                } // if
    320316                if ( type->get_atomic() ) {
    321317                        mangleName << "A";
  • src/SymTab/Validate.cc

    r74bba15 raf58ee0  
    5656#include "FixFunction.h"               // for FixFunction
    5757#include "Indexer.h"                   // for Indexer
    58 #include "InitTweak/GenInit.h"         // for fixReturnStatements
    5958#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    6059#include "Parser/LinkageSpec.h"        // for C
     
    151150        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    152151        struct ForallPointerDecay final {
    153                 void previsit( ObjectDecl * object );
    154                 void previsit( FunctionDecl * func );
     152                void previsit( ObjectDecl *object );
     153                void previsit( FunctionDecl *func );
    155154        };
    156155
     
    580579
    581580        /// Fix up assertions - flattens assertion lists, removing all trait instances
    582         void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
    583                 for ( TypeDecl * type : forall ) {
     581        void forallFixer( Type * func ) {
     582                for ( TypeDecl * type : func->get_forall() ) {
    584583                        std::list< DeclarationWithType * > asserts;
    585584                        asserts.splice( asserts.end(), type->assertions );
     
    600599                                assertion = assertion->acceptMutator( fixer );
    601600                                if ( fixer.get_isVoid() ) {
    602                                         throw SemanticError( "invalid type void in assertion of function ", node );
     601                                        throw SemanticError( "invalid type void in assertion of function ", func );
    603602                                } // if
    604603                        } // for
     
    608607
    609608        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    610                 forallFixer( object->type->forall, object );
    611                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
    612                         forallFixer( pointer->base->forall, object );
     609                forallFixer( object->get_type() );
     610                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     611                        forallFixer( pointer->get_base() );
    613612                } // if
    614613                object->fixUniqueId();
     
    616615
    617616        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    618                 forallFixer( func->type->forall, func );
     617                forallFixer( func->get_type() );
    619618                func->fixUniqueId();
    620619        }
  • src/SynTree/BaseSyntaxNode.h

    r74bba15 raf58ee0  
    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 
    31 std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node );
    3230
    3331// Local Variables: //
  • src/SynTree/CompoundStmt.cc

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

    r74bba15 raf58ee0  
    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 
    36 Constant Constant::from_char( char c ) {
    37         return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );
    3834}
    3935
  • src/SynTree/Constant.h

    r74bba15 raf58ee0  
    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 );
    4442        /// generates an integer constant of the given int
    4543        static Constant from_int( int i );
  • src/SynTree/Declaration.cc

    r74bba15 raf58ee0  
    5959}
    6060
     61std::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
    6170
    6271AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) {
  • src/SynTree/Declaration.h

    r74bba15 raf58ee0  
    6262        void fixUniqueId( void );
    6363        virtual Declaration *clone() const = 0;
    64         virtual void accept( Visitor &v ) override = 0;
     64        virtual void accept( Visitor &v ) = 0;
    6565        virtual Declaration *acceptMutator( Mutator &m ) = 0;
    66         virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
     66        virtual void print( std::ostream &os, int indent = 0 ) const = 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 override = 0;
    109         virtual DeclarationWithType *acceptMutator( Mutator &m )  override = 0;
     108        virtual DeclarationWithType *clone() const = 0;
     109        virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
    110110
    111111        virtual Type * get_type() const = 0;
     
    128128        virtual ~ObjectDecl();
    129129
    130         virtual Type * get_type() const override { return type; }
    131         virtual void set_type(Type *newType) override { type = newType; }
     130        virtual Type * get_type() const { return type; }
     131        virtual void set_type(Type *newType) { 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 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;
     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;
    146146};
    147147
     
    157157        virtual ~FunctionDecl();
    158158
    159         virtual Type * get_type() const override { return type; }
    160         virtual void set_type(Type * t) override { type = strict_dynamic_cast< FunctionType* >( t ); }
     159        Type * get_type() const { return type; }
     160        virtual void set_type(Type * t) { 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 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;
     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;
    172172};
    173173
     
    190190        virtual std::string typeString() const = 0;
    191191
    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;
     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;
    195195};
    196196
     
    227227        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    228228
    229         virtual std::string typeString() const override;
     229        virtual std::string typeString() const;
    230230        virtual std::string genTypeString() const;
    231231
    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;
     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;
    236236
    237237  private:
     
    245245        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    246246
    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 ); }
     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 ); }
    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 override;
    277         virtual void printShort( std::ostream &os, int indent = 0 ) const override;
     276        virtual void print( std::ostream &os, int indent = 0 ) const;
     277        virtual void printShort( std::ostream &os, int indent = 0 ) const;
    278278  protected:
    279279        virtual std::string typeString() const = 0;
     
    290290        bool is_thread() { return kind == DeclarationNode::Thread; }
    291291
    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 ); }
     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 ); }
    295295  private:
    296296        DeclarationNode::Aggregate kind;
    297         virtual std::string typeString() const override;
     297        virtual std::string typeString() const;
    298298};
    299299
     
    304304        UnionDecl( const UnionDecl &other ) : Parent( other ) {}
    305305
    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;
     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;
    311311};
    312312
     
    317317        EnumDecl( const EnumDecl &other ) : Parent( other ) {}
    318318
    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;
     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;
    324324};
    325325
     
    332332        TraitDecl( const TraitDecl &other ) : Parent( other ) {}
    333333
    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;
     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;
    339339};
    340340
     
    350350        void set_stmt( AsmStmt *newValue ) { stmt = newValue; }
    351351
    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 
     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
     359std::ostream & operator<<( std::ostream & out, const Declaration * decl );
    359360std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
    360361
  • src/SynTree/Expression.cc

    r74bba15 raf58ee0  
    741741}
    742742
     743
     744std::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
    743753// Local Variables: //
    744754// tab-width: 4 //
  • src/SynTree/Expression.h

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

    r74bba15 raf58ee0  
    137137}
    138138
     139std::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
     148std::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
    139157// Local Variables: //
    140158// tab-width: 4 //
  • src/SynTree/Initializer.h

    r74bba15 raf58ee0  
    3838
    3939        virtual Designation * clone() const { return new Designation( *this ); };
    40         virtual void accept( Visitor &v ) override { v.visit( this ); }
     40        virtual void accept( Visitor &v ) { v.visit( this ); }
    4141        virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
    42         virtual void print( std::ostream &os, int indent = 0 ) const override;
     42        virtual void print( std::ostream &os, int indent = 0 ) const;
    4343};
    4444
     
    5555
    5656        virtual Initializer *clone() const = 0;
    57         virtual void accept( Visitor &v ) override = 0;
     57        virtual void accept( Visitor &v ) = 0;
    5858        virtual Initializer *acceptMutator( Mutator &m ) = 0;
    59         virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
     59        virtual void print( std::ostream &os, int indent = 0 ) const = 0;
    6060  private:
    6161        bool maybeConstructed;
     
    7575        void set_value( Expression *newValue ) { value = newValue; }
    7676
    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;
     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;
    8181};
    8282
     
    103103        const_iterator end() const { return initializers.end(); }
    104104
    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;
     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;
    109109};
    110110
     
    129129        Initializer * get_init() const { return init; }
    130130
    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;
     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;
    135135
    136136  private:
     
    140140};
    141141
     142std::ostream & operator<<( std::ostream & out, const Initializer * init );
     143std::ostream & operator<<( std::ostream & out, const Designation * des );
     144
    142145// Local Variables: //
    143146// tab-width: 4 //
  • src/SynTree/Statement.cc

    r74bba15 raf58ee0  
    168168}
    169169
    170 SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, const std::list<Statement *> &statements ):
     170SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, std::list<Statement *> &statements ):
    171171        Statement( labels ), condition( condition ), statements( statements ) {
    172172}
     
    196196}
    197197
    198 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
     198CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
    199199        Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) {
    200200        if ( isDefault() && condition != 0 )
     
    497497}
    498498
     499std::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
    499508// Local Variables: //
    500509// tab-width: 4 //
  • src/SynTree/Statement.h

    r74bba15 raf58ee0  
    4444
    4545        virtual Statement *clone() const = 0;
    46         virtual void accept( Visitor &v ) override = 0;
     46        virtual void accept( Visitor &v ) = 0;
    4747        virtual Statement *acceptMutator( Mutator &m ) = 0;
    48         virtual void print( std::ostream &os, int indent = 0 ) const override;
     48        virtual void print( std::ostream &os, int indent = 0 ) const;
    4949};
    5050
     
    5454
    5555        CompoundStmt( std::list<Label> labels );
    56         CompoundStmt( std::list<Statement *> stmts );
    5756        CompoundStmt( const CompoundStmt &other );
    5857        virtual ~CompoundStmt();
     
    6261        void push_front( Statement * stmt ) { kids.push_front( stmt ); }
    6362
    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;
     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;
    6867};
    6968
     
    7372        NullStmt( std::list<Label> labels );
    7473
    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;
     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;
    7978};
    8079
     
    9089        void set_expr( Expression *newValue ) { expr = newValue; }
    9190
    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;
     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;
    9695};
    9796
     
    147146        void set_elsePart( Statement *newValue ) { elsePart = newValue; }
    148147
    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;
     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;
    153152};
    154153
     
    158157        std::list<Statement *> statements;
    159158
    160         SwitchStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements );
     159        SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements );
    161160        SwitchStmt( const SwitchStmt &other );
    162161        virtual ~SwitchStmt();
     
    167166        std::list<Statement *> & get_statements() { return statements; }
    168167
    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;
     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;
    174173
    175174};
     
    180179        std::list<Statement *> stmts;
    181180
    182         CaseStmt( std::list<Label> labels, Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
     181        CaseStmt( std::list<Label> labels, Expression *conditions, std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
    183182        CaseStmt( const CaseStmt &other );
    184183        virtual ~CaseStmt();
     
    195194        void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
    196195
    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;
     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;
    202201  private:
    203202        bool _isDefault;
     
    222221        void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
    223222
    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;
     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;
    228227};
    229228
     
    248247        void set_body( Statement *newValue ) { body = newValue; }
    249248
    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;
     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;
    254253};
    255254
     
    277276        const char *get_typename() { return brType[ type ]; }
    278277
    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;
     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;
    283282  private:
    284283        static const char *brType[];
     
    296295        void set_expr( Expression *newValue ) { expr = newValue; }
    297296
    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;
     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;
    302301};
    303302
     
    320319        void set_target( Expression * newTarget ) { target = newTarget; }
    321320
    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;
     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;
    326325};
    327326
     
    343342        void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
    344343
    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;
     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;
    349348};
    350349
     
    371370        void set_body( Statement *newValue ) { body = newValue; }
    372371
    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;
     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;
    377376};
    378377
     
    388387        void set_block( CompoundStmt *newValue ) { block = newValue; }
    389388
    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;
     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;
    394393};
    395394
     
    425424        } orelse;
    426425
    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;
     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;
    431430
    432431};
     
    445444        void set_decl( Declaration *newValue ) { decl = newValue; }
    446445
    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;
     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;
    451450};
    452451
     
    467466        void set_callStmt( Statement * newValue ) { callStmt = newValue; }
    468467
    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 };
     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
     475std::ostream & operator<<( std::ostream & out, const Statement * statement );
    474476
    475477// Local Variables: //
  • src/SynTree/Type.cc

    r74bba15 raf58ee0  
    9999const Type::Qualifiers noQualifiers;
    100100
     101std::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
    101110// Local Variables: //
    102111// tab-width: 4 //
  • src/SynTree/Type.h

    r74bba15 raf58ee0  
    192192        VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    193193
    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;
     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;
    201201};
    202202
     
    235235        void set_kind( Kind newValue ) { kind = newValue; }
    236236
    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;
     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;
    241241
    242242        bool isInteger() const;
     
    268268        bool is_array() const { return isStatic || isVarLen || dimension; }
    269269
    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;
     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;
    276276};
    277277
     
    296296        void set_isStatic( bool newValue ) { isStatic = newValue; }
    297297
    298         virtual bool isComplete() const override { return ! isVarLen; }
    299 
    300         virtual ArrayType *clone() const override { return new ArrayType( *this ); }
    301         virtual void accept( Visitor & v ) override { v.visit( this ); }
    302         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    303         virtual void print( std::ostream & os, int indent = 0 ) const override;
     298        virtual bool isComplete() const { return ! isVarLen; }
     299
     300        virtual ArrayType *clone() const { return new ArrayType( *this ); }
     301        virtual void accept( Visitor & v ) { v.visit( this ); }
     302        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     303        virtual void print( std::ostream & os, int indent = 0 ) const;
    304304};
    305305
     
    315315        void set_base( Type *newValue ) { base = newValue; }
    316316
    317         virtual int referenceDepth() const override;
     317        virtual int referenceDepth() const;
    318318
    319319        // Since reference types act like value types, their size is the size of the base.
    320320        // This makes it simple to cast the empty tuple to a reference type, since casts that increase
    321321        // the number of values are disallowed.
    322         virtual unsigned size() const override { return base->size(); }
    323 
    324         virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
    325         virtual void accept( Visitor & v ) override { v.visit( this ); }
    326         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    327         virtual void print( std::ostream & os, int indent = 0 ) const override;
     322        virtual unsigned size() const { return base->size(); }
     323
     324        virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
     325        virtual void accept( Visitor & v ) { v.visit( this ); }
     326        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     327        virtual void print( std::ostream & os, int indent = 0 ) const;
    328328};
    329329
     
    349349        bool isTtype() const;
    350350
    351         virtual FunctionType *clone() const override { return new FunctionType( *this ); }
    352         virtual void accept( Visitor & v ) override { v.visit( this ); }
    353         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    354         virtual void print( std::ostream & os, int indent = 0 ) const override;
     351        virtual FunctionType *clone() const { return new FunctionType( *this ); }
     352        virtual void accept( Visitor & v ) { v.visit( this ); }
     353        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     354        virtual void print( std::ostream & os, int indent = 0 ) const;
    355355};
    356356
     
    371371        void set_hoistType( bool newValue ) { hoistType = newValue; }
    372372
    373         virtual ReferenceToType *clone() const override = 0;
    374         virtual void accept( Visitor & v ) override = 0;
    375         virtual Type *acceptMutator( Mutator & m ) override = 0;
    376         virtual void print( std::ostream & os, int indent = 0 ) const override;
     373        virtual ReferenceToType *clone() const = 0;
     374        virtual void accept( Visitor & v ) = 0;
     375        virtual Type *acceptMutator( Mutator & m ) = 0;
     376        virtual void print( std::ostream & os, int indent = 0 ) const;
    377377
    378378        virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
     
    398398        std::list<TypeDecl*> * get_baseParameters();
    399399
    400         virtual bool isComplete() const override;
     400        virtual bool isComplete() const;
    401401
    402402        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    403403        /// Clones declarations into "foundDecls", caller responsible for freeing
    404         void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
    405 
    406         virtual StructInstType *clone() const override { return new StructInstType( *this ); }
    407         virtual void accept( Visitor & v ) override { v.visit( this ); }
    408         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    409 
    410         virtual void print( std::ostream & os, int indent = 0 ) const override;
     404        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const;
     405
     406        virtual StructInstType *clone() const { return new StructInstType( *this ); }
     407        virtual void accept( Visitor & v ) { v.visit( this ); }
     408        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     409
     410        virtual void print( std::ostream & os, int indent = 0 ) const;
    411411  private:
    412         virtual std::string typeString() const override;
     412        virtual std::string typeString() const;
    413413};
    414414
     
    430430        std::list< TypeDecl * > * get_baseParameters();
    431431
    432         virtual bool isComplete() const override;
     432        virtual bool isComplete() const;
    433433
    434434        /// looks up the members of this union named "name" and places them into "foundDecls"
    435435        /// Clones declarations into "foundDecls", caller responsible for freeing
    436         void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
    437 
    438         virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
    439         virtual void accept( Visitor & v ) override { v.visit( this ); }
    440         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    441 
    442         virtual void print( std::ostream & os, int indent = 0 ) const override;
     436        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const;
     437
     438        virtual UnionInstType *clone() const { return new UnionInstType( *this ); }
     439        virtual void accept( Visitor & v ) { v.visit( this ); }
     440        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     441
     442        virtual void print( std::ostream & os, int indent = 0 ) const;
    443443  private:
    444         virtual std::string typeString() const override;
     444        virtual std::string typeString() const;
    445445};
    446446
     
    459459        void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
    460460
    461         virtual bool isComplete() const override;
    462 
    463         virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
    464         virtual void accept( Visitor & v ) override { v.visit( this ); }
    465         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     461        virtual bool isComplete() const;
     462
     463        virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
     464        virtual void accept( Visitor & v ) { v.visit( this ); }
     465        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
    466466  private:
    467         virtual std::string typeString() const override;
     467        virtual std::string typeString() const;
    468468};
    469469
     
    480480        ~TraitInstType();
    481481
    482         virtual bool isComplete() const override;
    483 
    484         virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
    485         virtual void accept( Visitor & v ) override { v.visit( this ); }
    486         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     482        virtual bool isComplete() const;
     483
     484        virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
     485        virtual void accept( Visitor & v ) { v.visit( this ); }
     486        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
    487487  private:
    488         virtual std::string typeString() const override;
     488        virtual std::string typeString() const;
    489489};
    490490
     
    507507        void set_isFtype( bool newValue ) { isFtype = newValue; }
    508508
    509         virtual bool isComplete() const override;
    510 
    511         virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
    512         virtual void accept( Visitor & v ) override { v.visit( this ); }
    513         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    514         virtual void print( std::ostream & os, int indent = 0 ) const override;
     509        virtual bool isComplete() const;
     510
     511        virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
     512        virtual void accept( Visitor & v ) { v.visit( this ); }
     513        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     514        virtual void print( std::ostream & os, int indent = 0 ) const;
    515515  private:
    516         virtual std::string typeString() const override;
     516        virtual std::string typeString() const;
    517517};
    518518
     
    530530
    531531        std::list<Type *> & get_types() { return types; }
    532         virtual unsigned size() const override { return types.size(); };
     532        virtual unsigned size() const { return types.size(); };
    533533
    534534        // For now, this is entirely synthetic -- tuple types always have unnamed members.
     
    539539        iterator end() { return types.end(); }
    540540
    541         virtual Type * getComponent( unsigned i ) override {
     541        virtual Type * getComponent( unsigned i ) {
    542542                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
    543543                return *(begin()+i);
    544544        }
    545545
    546         // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
    547 
    548         virtual TupleType *clone() const override { return new TupleType( *this ); }
    549         virtual void accept( Visitor & v ) override { v.visit( this ); }
    550         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    551         virtual void print( std::ostream & os, int indent = 0 ) const override;
     546        // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
     547
     548        virtual TupleType *clone() const { return new TupleType( *this ); }
     549        virtual void accept( Visitor & v ) { v.visit( this ); }
     550        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     551        virtual void print( std::ostream & os, int indent = 0 ) const;
    552552};
    553553
     
    563563        void set_expr( Expression *newValue ) { expr = newValue; }
    564564
    565         virtual bool isComplete() const override { assert( false ); return false; }
    566 
    567         virtual TypeofType *clone() const override { return new TypeofType( *this ); }
    568         virtual void accept( Visitor & v ) override { v.visit( this ); }
    569         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    570         virtual void print( std::ostream & os, int indent = 0 ) const override;
     565        virtual bool isComplete() const { assert( false ); return false; }
     566
     567        virtual TypeofType *clone() const { return new TypeofType( *this ); }
     568        virtual void accept( Visitor & v ) { v.visit( this ); }
     569        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     570        virtual void print( std::ostream & os, int indent = 0 ) const;
    571571};
    572572
     
    592592        void set_isType( bool newValue ) { isType = newValue; }
    593593
    594         virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
    595 
    596         virtual AttrType *clone() const override { return new AttrType( *this ); }
    597         virtual void accept( Visitor & v ) override { v.visit( this ); }
    598         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    599         virtual void print( std::ostream & os, int indent = 0 ) const override;
     594        virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
     595
     596        virtual AttrType *clone() const { return new AttrType( *this ); }
     597        virtual void accept( Visitor & v ) { v.visit( this ); }
     598        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     599        virtual void print( std::ostream & os, int indent = 0 ) const;
    600600};
    601601
     
    606606        VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    607607
    608         virtual bool isComplete() const override{ return true; } // xxx - is this right?
    609 
    610         virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
    611         virtual void accept( Visitor & v ) override { v.visit( this ); }
    612         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    613         virtual void print( std::ostream & os, int indent = 0 ) const override;
     608        virtual bool isComplete() const{ return true; } // xxx - is this right?
     609
     610        virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
     611        virtual void accept( Visitor & v ) { v.visit( this ); }
     612        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     613        virtual void print( std::ostream & os, int indent = 0 ) const;
    614614};
    615615
     
    620620        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    621621
    622         virtual ZeroType *clone() const override { return new ZeroType( *this ); }
    623         virtual void accept( Visitor & v ) override { v.visit( this ); }
    624         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    625         virtual void print( std::ostream & os, int indent = 0 ) const override;
     622        virtual ZeroType *clone() const { return new ZeroType( *this ); }
     623        virtual void accept( Visitor & v ) { v.visit( this ); }
     624        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     625        virtual void print( std::ostream & os, int indent = 0 ) const;
    626626};
    627627
     
    632632        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    633633
    634         virtual OneType *clone() const override { return new OneType( *this ); }
    635         virtual void accept( Visitor & v ) override { v.visit( this ); }
    636         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    637         virtual void print( std::ostream & os, int indent = 0 ) const override;
    638 };
     634        virtual OneType *clone() const { return new OneType( *this ); }
     635        virtual void accept( Visitor & v ) { v.visit( this ); }
     636        virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
     637        virtual void print( std::ostream & os, int indent = 0 ) const;
     638};
     639
     640std::ostream & operator<<( std::ostream & out, const Type * type );
    639641
    640642// Local Variables: //
  • src/SynTree/Visitor.h

    r74bba15 raf58ee0  
    2525  public:
    2626        // visit: Default implementation of all functions visits the children
    27         // of the given syntax node, but performs no other action.
     27    // of the given syntax node, but performs no other action.
    2828
    2929        virtual void visit( ObjectDecl *objectDecl );
  • src/SynTree/module.mk

    r74bba15 raf58ee0  
    4848       SynTree/Visitor.cc \
    4949       SynTree/Mutator.cc \
     50       SynTree/AddStmtVisitor.cc \
    5051       SynTree/TypeSubstitution.cc \
    5152       SynTree/Attribute.cc \
  • src/Tuples/TupleExpansion.cc

    r74bba15 raf58ee0  
    2121#include "Common/ScopedMap.h"     // for ScopedMap
    2222#include "Common/utility.h"       // for CodeLocation
     23#include "GenPoly/DeclMutator.h"  // for DeclMutator
    2324#include "InitTweak/InitTweak.h"  // for getFunction
    2425#include "Parser/LinkageSpec.h"   // for Spec, C, Intrinsic
  • src/benchmark/bench.h

    r74bba15 raf58ee0  
    1111#endif
    1212
    13 static inline unsigned long long int Time() {
     13inline unsigned long long int Time() {
    1414    struct timespec ts;
    1515    clock_gettime(
  • src/libcfa/Makefile.am

    r74bba15 raf58ee0  
    3636         ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $<
    3737
    38 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
     38EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    3939
    4040AM_CCASFLAGS = @CFA_FLAGS@
  • src/libcfa/Makefile.in

    r74bba15 raf58ee0  
    416416ARFLAGS = cr
    417417lib_LIBRARIES = $(am__append_1) $(am__append_2)
    418 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
     418EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    419419AM_CCASFLAGS = @CFA_FLAGS@
    420420headers = fstream iostream iterator limits rational stdlib \
  • src/libcfa/concurrency/coroutine.c

    r74bba15 raf58ee0  
    123123        if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE );
    124124
     125        LIB_DEBUG_PRINT_SAFE("FRED");
     126
    125127        size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment
    126128
  • src/libcfa/concurrency/invoke.h

    r74bba15 raf58ee0  
    8484      };
    8585
    86       struct __waitfor_mask_t {
    87             short * accepted;                         // the index of the accepted function, -1 if none
    88             struct __acceptable_t * clauses;          // list of acceptable functions, null if any
    89             short size;                               // number of acceptable functions
    90       };
    91 
    9286      struct monitor_desc {
    9387            struct spinlock lock;                     // spinlock to protect internal data
     
    9690            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    9791            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    98             struct __waitfor_mask_t mask;               // mask used to know if some thread is waiting for something while holding the monitor
    99       };
    10092
    101       struct __monitor_group_t {
    102             struct monitor_desc ** list;              // currently held monitors
    103             short                  size;              // number of currently held monitors
    104             fptr_t                 func;              // last function that acquired monitors
    105       };
     93            struct __acceptable_t * acceptables;      // list of acceptable functions, null if any
     94            unsigned short acceptable_count;          // number of acceptable functions
     95            short accepted_index;                     // the index of the accepted function, -1 if none
     96       };
    10697
    10798      struct thread_desc {
    10899            // Core threading fields
    109             struct coroutine_desc  self_cor;          // coroutine body used to store context
    110             struct monitor_desc    self_mon;          // monitor body used for mutual exclusion
    111             struct monitor_desc *  self_mon_p;        // pointer to monitor with sufficient lifetime for current monitors
    112             struct __monitor_group_t monitors;          // monitors currently held by this thread
     100            struct coroutine_desc cor;                // coroutine body used to store context
     101            struct monitor_desc mon;                  // monitor body used for mutual exclusion
    113102
    114103            // Link lists fields
    115104            struct thread_desc * next;                // instrusive link field for threads
    116105
    117 
     106            // Current status related to monitors
     107            struct monitor_desc ** current_monitors;  // currently held monitors
     108            unsigned short current_monitor_count;     // number of currently held monitors
     109            fptr_t current_monitor_func;              // last function that acquired monitors
    118110     };
    119 
    120      #ifdef __CFORALL__
    121      extern "Cforall" {
    122             static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    123                   return this.list[index];
    124             }
    125 
    126             static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
    127                   if( (lhs.list != 0) != (rhs.list != 0) ) return false;
    128                   if( lhs.size != rhs.size ) return false;
    129                   if( lhs.func != rhs.func ) return false;
    130 
    131                   // Check that all the monitors match
    132                   for( int i = 0; i < lhs.size; i++ ) {
    133                         // If not a match, check next function
    134                         if( lhs[i] != rhs[i] ) return false;
    135                   }
    136 
    137                   return true;
    138             }
    139       }
    140       #endif
    141111
    142112#endif //_INVOKE_H_
  • src/libcfa/concurrency/kernel.c

    r74bba15 raf58ee0  
    106106
    107107void ?{}( thread_desc & this, current_stack_info_t * info) {
    108         (this.self_cor){ info };
     108        (this.cor){ info };
    109109}
    110110
     
    328328        // if( !thrd ) return;
    329329        verify( thrd );
    330         verify( thrd->self_cor.state != Halted );
     330        verify( thrd->cor.state != Halted );
    331331
    332332        verify( disable_preempt_count > 0 );
     
    373373        assert(thrd);
    374374        disable_interrupts();
    375         assert( thrd->self_cor.state != Halted );
     375        assert( thrd->cor.state != Halted );
    376376        this_processor->finish.action_code = Schedule;
    377377        this_processor->finish.thrd = thrd;
     
    466466        this_processor = mainProcessor;
    467467        this_thread = mainThread;
    468         this_coroutine = &mainThread->self_cor;
     468        this_coroutine = &mainThread->cor;
    469469
    470470        // Enable preemption
     
    547547        thread_desc * thrd = kernel_data;
    548548
    549         int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd );
     549        int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->cor.name, thrd );
    550550        __lib_debug_write( STDERR_FILENO, abort_text, len );
    551551
  • src/libcfa/concurrency/monitor

    r74bba15 raf58ee0  
    2222#include "stdlib"
    2323
    24 trait is_monitor(dtype T) {
    25         monitor_desc * get_monitor( T & );
    26         void ^?{}( T & mutex );
    27 };
    28 
    2924static inline void ?{}(monitor_desc & this) {
    3025        (this.lock){};
     
    3328        (this.signal_stack){};
    3429        this.recursion = 0;
    35         this.mask.accepted = NULL;
    36         this.mask.clauses  = NULL;
    37         this.mask.size     = 0;
     30        this.acceptables = NULL;
     31        this.acceptable_count = 0;
     32        this.accepted_index = -1;
    3833}
    3934
     
    105100
    106101struct __acceptable_t {
    107         __monitor_group_t;
     102        fptr_t func;
     103        unsigned short count;
     104        monitor_desc ** monitors;
    108105        bool is_dtor;
    109106};
    110107
    111 void __waitfor_internal( const __waitfor_mask_t & mask, int duration );
     108int __accept_internal( unsigned short count, __acceptable_t * acceptables );
    112109
    113110// Local Variables: //
  • src/libcfa/concurrency/monitor.c

    r74bba15 raf58ee0  
    2323//-----------------------------------------------------------------------------
    2424// Forward declarations
    25 static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    26 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner );
    27 static inline void set_mask  ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
    28 static inline void reset_mask( monitor_desc * this );
    29 
     25static inline void set_owner( monitor_desc * this, thread_desc * owner );
    3026static inline thread_desc * next_thread( monitor_desc * this );
    31 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
     27static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );
    3228
    3329static inline void lock_all( spinlock ** locks, unsigned short count );
     
    3632static inline void unlock_all( monitor_desc ** locks, unsigned short count );
    3733
    38 static inline void save   ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks );
    39 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks );
     34static inline void save_recursion   ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count );
     35static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
    4036
    4137static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    4238static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    4339
    44 static inline thread_desc *        check_condition   ( __condition_criterion_t * );
    45 static inline void                 brand_condition   ( condition * );
    46 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count );
    47 
    48 forall(dtype T | sized( T ))
    49 static inline short insert_unique( T ** array, short & size, T * val );
    50 static inline short count_max    ( const __waitfor_mask_t & mask );
    51 static inline short aggregate    ( monitor_desc ** storage, const __waitfor_mask_t & mask );
     40static inline thread_desc * check_condition( __condition_criterion_t * );
     41static inline void brand_condition( condition * );
     42static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
     43
     44static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
    5245
    5346//-----------------------------------------------------------------------------
    5447// Useful defines
    55 #define wait_ctx(thrd, user_info)                               /* Create the necessary information to use the signaller stack                         */ \
    56         __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    57         __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    58         init( count, monitors, &waiter, criteria );               /* Link everything together                                                            */ \
    59 
    60 #define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack                         */ \
    61         __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    62         __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    63         init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack                                */ \
    64 
    65 #define monitor_ctx( mons, cnt )                                /* Define that create the necessary struct for internal/external scheduling operations */ \
    66         monitor_desc ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
    67         unsigned short count = cnt;                               /* Save the count to a local variable                                                  */ \
    68         unsigned int recursions[ count ];                         /* Save the current recursion levels to restore them later                             */ \
    69         __waitfor_mask_t masks[ count ];                          /* Save the current waitfor masks to restore them later                                */ \
    70         spinlock *   locks     [ count ];                         /* We need to pass-in an array of locks to BlockInternal                               */ \
    71 
    72 #define monitor_save    save   ( monitors, count, locks, recursions, masks )
    73 #define monitor_restore restore( monitors, count, locks, recursions, masks )
    74 
     48#define wait_ctx(thrd, user_info)                               /* Create the necessary information to use the signaller stack       */ \
     49        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
     50        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
     51        init( count, monitors, &waiter, criteria );               /* Link everything together                                          */ \
     52
     53#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack       */ \
     54        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
     55        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
     56        init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack              */ \
     57
     58#define monitor_ctx( mons, cnt )              /* Define that create the necessary struct for internal/external scheduling operations */ \
     59        monitor_desc ** monitors = mons;        /* Save the targeted monitors                                                          */ \
     60        unsigned short count = cnt;             /* Save the count to a local variable                                                  */ \
     61        unsigned int recursions[ count ];       /* Save the current recursion levels to restore them later                             */ \
     62        spinlock *   locks     [ count ];       /* We need to pass-in an array of locks to BlockInternal                               */ \
    7563
    7664//-----------------------------------------------------------------------------
     
    8068extern "C" {
    8169        // Enter single monitor
    82         static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
     70        static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
    8371                // Lock the monitor spinlock, lock_yield to reduce contention
    8472                lock_yield( &this->lock DEBUG_CTX2 );
     
    8775                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    8876
     77                this->accepted_index = -1;
    8978                if( !this->owner ) {
    9079                        // No one has the monitor, just take it
     
    10089                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
    10190                }
    102                 else if( is_accepted( this, group) ) {
     91                else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {
    10392                        // Some one was waiting for us, enter
    10493                        set_owner( this, thrd );
    105 
    106                         // Reset mask
    107                         reset_mask( this );
    10894
    10995                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
     
    134120                lock_yield( &this->lock DEBUG_CTX2 );
    135121
    136                 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
    137 
    138                 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this );
     122                verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
    139123
    140124                // Leaving a recursion level, decrement the counter
     
    162146        // Should never return
    163147        void __leave_thread_monitor( thread_desc * thrd ) {
    164                 monitor_desc * this = &thrd->self_mon;
     148                monitor_desc * this = &thrd->mon;
    165149
    166150                // Lock the monitor now
     
    169153                disable_interrupts();
    170154
    171                 thrd->self_cor.state = Halted;
    172 
    173                 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", thrd, this->owner, this->recursion, this );
     155                thrd->cor.state = Halted;
     156
     157                verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    174158
    175159                // Leaving a recursion level, decrement the counter
     
    194178// Enter multiple monitor
    195179// relies on the monitor array being sorted
    196 static inline void enter( __monitor_group_t monitors ) {
    197         for(int i = 0; i < monitors.size; i++) {
    198                 __enter_monitor_desc( monitors.list[i], monitors );
     180static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) {
     181        for(int i = 0; i < count; i++) {
     182                __enter_monitor_desc( monitors[i], monitors, count, func );
    199183        }
    200184}
     
    219203
    220204        // Save previous thread context
    221         this.prev_mntrs = this_thread->monitors.list;
    222         this.prev_count = this_thread->monitors.size;
    223         this.prev_func  = this_thread->monitors.func;
     205        this.prev_mntrs = this_thread->current_monitors;
     206        this.prev_count = this_thread->current_monitor_count;
     207        this.prev_func  = this_thread->current_monitor_func;
    224208
    225209        // Update thread context (needed for conditions)
    226         this_thread->monitors.list = m;
    227         this_thread->monitors.size = count;
    228         this_thread->monitors.func = func;
    229 
    230         // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     210        this_thread->current_monitors      = m;
     211        this_thread->current_monitor_count = count;
     212        this_thread->current_monitor_func  = func;
    231213
    232214        // Enter the monitors in order
    233         __monitor_group_t group = {this.m, this.count, func};
    234         enter( group );
    235 
    236         // LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");
     215        enter( this.m, this.count, func );
    237216}
    238217
     
    240219// Dtor for monitor guard
    241220void ^?{}( monitor_guard_t & this ) {
    242         // LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);
    243 
    244221        // Leave the monitors in order
    245222        leave( this.m, this.count );
    246223
    247         // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
    248 
    249224        // Restore thread context
    250         this_thread->monitors.list = this.prev_mntrs;
    251         this_thread->monitors.size = this.prev_count;
    252         this_thread->monitors.func = this.prev_func;
     225        this_thread->current_monitors      = this.prev_mntrs;
     226        this_thread->current_monitor_count = this.prev_count;
     227        this_thread->current_monitor_func = this.prev_func;
    253228}
    254229
     
    296271        append( &this->blocked, &waiter );
    297272
    298         // Lock all monitors (aggregates the locks as well)
     273        // Lock all monitors (aggregates the lock them as well)
    299274        lock_all( monitors, locks, count );
    300275
     276        // DON'T unlock, ask the kernel to do it
     277
     278        // Save monitor state
     279        save_recursion( monitors, recursions, count );
     280
    301281        // Find the next thread(s) to run
    302         short thread_count = 0;
     282        unsigned short thread_count = 0;
    303283        thread_desc * threads[ count ];
    304284        for(int i = 0; i < count; i++) {
     
    306286        }
    307287
    308         // Save monitor states
    309         monitor_save;
    310 
    311288        // Remove any duplicate threads
    312289        for( int i = 0; i < count; i++) {
    313290                thread_desc * new_owner = next_thread( monitors[i] );
    314                 insert_unique( threads, thread_count, new_owner );
     291                thread_count = insert_unique( threads, thread_count, new_owner );
    315292        }
    316293
     
    318295        BlockInternal( locks, count, threads, thread_count );
    319296
     297
     298        // WE WOKE UP
     299
     300
    320301        // We are back, restore the owners and recursions
    321         monitor_restore;
     302        lock_all( locks, count );
     303        restore_recursion( monitors, recursions, count );
     304        unlock_all( locks, count );
    322305}
    323306
     
    332315        LIB_DEBUG_DO(
    333316                thread_desc * this_thrd = this_thread;
    334                 if ( this->monitor_count != this_thrd->monitors.size ) {
    335                         abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );
     317                if ( this->monitor_count != this_thrd->current_monitor_count ) {
     318                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
    336319                }
    337320
    338321                for(int i = 0; i < this->monitor_count; i++) {
    339                         if ( this->monitors[i] != this_thrd->monitors.list[i] ) {
    340                                 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );
     322                        if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
     323                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
    341324                        }
    342325                }
     
    381364
    382365        //save contexts
    383         monitor_save;
     366        save_recursion( monitors, recursions, count );
    384367
    385368        //Find the thread to run
    386369        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
    387         set_owner( monitors, count, signallee );
     370        for(int i = 0; i < count; i++) {
     371                set_owner( monitors[i], signallee );
     372        }
    388373
    389374        //Everything is ready to go to sleep
     
    394379
    395380
    396         //We are back, restore the masks and recursions
    397         monitor_restore;
     381        //We are back, restore the owners and recursions
     382        lock_all( locks, count );
     383        restore_recursion( monitors, recursions, count );
     384        unlock_all( locks, count );
    398385
    399386        return true;
     
    410397
    411398//-----------------------------------------------------------------------------
    412 // External scheduling
    413 // cases to handle :
    414 //      - target already there :
    415 //              block and wake
    416 //      - dtor already there
    417 //              put thread on signaller stack
    418 //      - non-blocking
    419 //              return else
    420 //      - timeout
    421 //              return timeout
    422 //      - block
    423 //              setup mask
    424 //              block
    425 void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) {
    426         // This statment doesn't have a contiguous list of monitors...
    427         // Create one!
    428         short max = count_max( mask );
    429         monitor_desc * mon_storage[max];
    430         short actual_count = aggregate( mon_storage, mask );
    431 
    432         if(actual_count == 0) return;
    433 
    434         LIB_DEBUG_PRINT_SAFE("Kernel : waitfor internal proceeding\n");
     399// Internal scheduling
     400int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
     401        thread_desc * thrd = this_thread;
    435402
    436403        // Create storage for monitor context
    437         monitor_ctx( mon_storage, actual_count );
    438 
    439         // Lock all monitors (aggregates the locks as well)
     404        monitor_ctx( acceptables->monitors, acceptables->count );
     405
     406        // Lock all monitors (aggregates the lock them as well)
    440407        lock_all( monitors, locks, count );
    441408
    442         {
    443                 // Check if the entry queue
    444                 thread_desc * next; int index;
    445                 [next, index] = search_entry_queue( mask, monitors, count );
    446 
    447                 if( next ) {
    448                         *mask.accepted = index;
    449                         if( mask.clauses[index].is_dtor ) {
    450                                 #warning case not implemented
    451                         }
    452                         else {
    453                                 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, baton-passing\n");
    454 
    455                                 // Create the node specific to this wait operation
    456                                 wait_ctx_primed( this_thread, 0 );
    457 
    458                                 // Save monitor states
    459                                 monitor_save;
    460 
    461                                 // Set the owners to be the next thread
    462                                 set_owner( monitors, count, next );
    463 
    464                                 // Everything is ready to go to sleep
    465                                 BlockInternal( locks, count, &next, 1 );
    466 
    467                                 // We are back, restore the owners and recursions
    468                                 monitor_restore;
    469 
    470                                 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, returned\n");
    471                         }
    472 
    473                         LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);
    474 
    475                         return;
    476                 }
    477         }
    478 
    479 
    480         if( duration == 0 ) {
    481                 LIB_DEBUG_PRINT_SAFE("Kernel : non-blocking, exiting\n");
    482 
    483                 unlock_all( locks, count );
    484 
    485                 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);
    486                 return;
    487         }
    488 
    489 
    490         verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
    491 
    492         LIB_DEBUG_PRINT_SAFE("Kernel : blocking waitfor\n");
    493 
    494409        // Create the node specific to this wait operation
    495         wait_ctx_primed( this_thread, 0 );
    496 
    497         monitor_save;
    498         set_mask( monitors, count, mask );
    499 
     410        wait_ctx_primed( thrd, 0 );
     411
     412        // Check if the entry queue
     413        thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count );
     414
     415        LIB_DEBUG_PRINT_SAFE("Owner(s) :");
    500416        for(int i = 0; i < count; i++) {
    501                 verify( monitors[i]->owner == this_thread );
    502         }
    503 
    504         //Everything is ready to go to sleep
    505         BlockInternal( locks, count );
    506 
    507 
    508         // WE WOKE UP
    509 
    510 
    511         //We are back, restore the masks and recursions
    512         monitor_restore;
    513 
    514         LIB_DEBUG_PRINT_SAFE("Kernel : exiting\n");
    515 
    516         LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);
     417                LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner );
     418        }
     419        LIB_DEBUG_PRINT_SAFE("\n");
     420
     421        LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next);
     422
     423        if( !next ) {
     424                // Update acceptables on the current monitors
     425                for(int i = 0; i < count; i++) {
     426                        monitors[i]->acceptables = acceptables;
     427                        monitors[i]->acceptable_count = acc_count;
     428                }
     429        }
     430        else {
     431                for(int i = 0; i < count; i++) {
     432                        set_owner( monitors[i], next );
     433                }
     434        }
     435
     436
     437        save_recursion( monitors, recursions, count );
     438
     439
     440        // Everything is ready to go to sleep
     441        BlockInternal( locks, count, &next, next ? 1 : 0 );
     442
     443
     444        //WE WOKE UP
     445
     446
     447        //We are back, restore the owners and recursions
     448        lock_all( locks, count );
     449        restore_recursion( monitors, recursions, count );
     450        int acc_idx = monitors[0]->accepted_index;
     451        unlock_all( locks, count );
     452
     453        return acc_idx;
    517454}
    518455
     
    521458
    522459static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
    523         // LIB_DEBUG_PRINT_SAFE("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
    524 
    525460        //Pass the monitor appropriately
    526461        this->owner = owner;
     
    528463        //We are passing the monitor to someone else, which means recursion level is not 0
    529464        this->recursion = owner ? 1 : 0;
    530 }
    531 
    532 static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {
    533         for( int i = 0; i < count; i++ ) {
    534                 set_owner( monitors[i], owner );
    535         }
    536 }
    537 
    538 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
    539         for(int i = 0; i < count; i++) {
    540                 storage[i]->mask = mask;
    541         }
    542 }
    543 
    544 static inline void reset_mask( monitor_desc * this ) {
    545         this->mask.accepted = NULL;
    546         this->mask.clauses = NULL;
    547         this->mask.size = 0;
    548465}
    549466
     
    568485}
    569486
    570 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    571         __acceptable_t * it = this->mask.clauses; // Optim
    572         int count = this->mask.size;
     487static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
     488        __acceptable_t* accs = this->acceptables; // Optim
     489        int acc_cnt = this->acceptable_count;
    573490
    574491        // Check if there are any acceptable functions
    575         if( !it ) return false;
     492        if( !accs ) return -1;
    576493
    577494        // If this isn't the first monitor to test this, there is no reason to repeat the test.
    578         if( this != group[0] ) return group[0]->mask.accepted >= 0;
     495        if( this != group[0] ) return group[0]->accepted_index;
    579496
    580497        // For all acceptable functions check if this is the current function.
    581         for( short i = 0; i < count; i++, it++ ) {
    582                 if( *it == group ) {
    583                         *this->mask.accepted = i;
    584                         return true;
     498        OUT_LOOP:
     499        for( int i = 0; i < acc_cnt; i++ ) {
     500                __acceptable_t * acc = &accs[i];
     501
     502                // if function matches, check the monitors
     503                if( acc->func == func ) {
     504
     505                        // If the group count is different then it can't be a match
     506                        if( acc->count != group_cnt ) return -1;
     507
     508                        // Check that all the monitors match
     509                        for( int j = 0; j < group_cnt; j++ ) {
     510                                // If not a match, check next function
     511                                if( acc->monitors[j] != group[j] ) continue OUT_LOOP;
     512                        }
     513
     514                        // It's a complete match, accept the call
     515                        return i;
    585516                }
    586517        }
    587518
    588519        // No function matched
    589         return false;
     520        return -1;
    590521}
    591522
     
    633564}
    634565
    635 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
     566
     567static inline void save_recursion   ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ) {
    636568        for( int i = 0; i < count; i++ ) {
    637569                recursions[i] = ctx[i]->recursion;
    638                 masks[i]      = ctx[i]->mask;
    639         }
    640 }
    641 
    642 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
    643         lock_all( locks, count );
     570        }
     571}
     572
     573static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ) {
    644574        for( int i = 0; i < count; i++ ) {
    645575                ctx[i]->recursion = recursions[i];
    646                 ctx[i]->mask      = masks[i];
    647         }
    648         unlock_all( locks, count );
     576        }
    649577}
    650578
     
    679607        if( !this->monitors ) {
    680608                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    681                 assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
    682                 this->monitor_count = thrd->monitors.size;
     609                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition %p", thrd->current_monitors );
     610                this->monitor_count = thrd->current_monitor_count;
    683611
    684612                this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );
    685613                for( int i = 0; i < this->monitor_count; i++ ) {
    686                         this->monitors[i] = thrd->monitors.list[i];
    687                 }
    688         }
    689 }
    690 
    691 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) {
     614                        this->monitors[i] = thrd->current_monitors[i];
     615                }
     616        }
     617}
     618
     619static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ) {
     620        if( !val ) return end;
     621
     622        for(int i = 0; i <= end; i++) {
     623                if( thrds[i] == val ) return end;
     624        }
     625
     626        thrds[end] = val;
     627        return end + 1;
     628}
     629
     630
     631static inline bool match( __acceptable_t * acc, thread_desc * thrd ) {
     632        verify( thrd );
     633        verify( acc );
     634        if( acc->func != thrd->current_monitor_func ) return false;
     635
     636        return true;
     637}
     638
     639static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
    692640
    693641        __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
     
    696644        for(    thread_desc ** thrd_it = &entry_queue->head;
    697645                *thrd_it;
    698                 thrd_it = &(*thrd_it)->next
    699         ) {
     646                thrd_it = &(*thrd_it)->next)
     647        {
    700648                // For each acceptable check if it matches
    701                 int i = 0;
    702                 __acceptable_t * end = mask.clauses + mask.size;
    703                 for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) {
     649                __acceptable_t * acc_end = acceptables + acc_count;
     650                for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) {
    704651                        // Check if we have a match
    705                         if( *it == (*thrd_it)->monitors ) {
     652                        if( match( acc_it, *thrd_it ) ) {
    706653
    707654                                // If we have a match return it
    708655                                // after removeing it from the entry queue
    709                                 return [remove( entry_queue, thrd_it ), i];
     656                                return remove( entry_queue, thrd_it );
    710657                        }
    711658                }
    712659        }
    713660
    714         return [0, -1];
    715 }
    716 
    717 forall(dtype T | sized( T ))
    718 static inline short insert_unique( T ** array, short & size, T * val ) {
    719         if( !val ) return size;
    720 
    721         for(int i = 0; i <= size; i++) {
    722                 if( array[i] == val ) return size;
    723         }
    724 
    725         array[size] = val;
    726         size = size + 1;
    727         return size;
    728 }
    729 
    730 static inline short count_max( const __waitfor_mask_t & mask ) {
    731         short max = 0;
    732         for( int i = 0; i < mask.size; i++ ) {
    733                 max += mask.clauses[i].size;
    734         }
    735         return max;
    736 }
    737 
    738 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
    739         short size = 0;
    740         for( int i = 0; i < mask.size; i++ ) {
    741                 for( int j = 0; j < mask.clauses[i].size; j++) {
    742                         insert_unique( storage, size, mask.clauses[i].list[j] );
    743                 }
    744         }
    745         qsort( storage, size );
    746         return size;
    747 }
    748 
     661        return NULL;
     662}
    749663void ?{}( __condition_blocked_queue_t & this ) {
    750664        this.head = NULL;
  • src/libcfa/concurrency/preemption.c

    r74bba15 raf58ee0  
    328328                siginfo_t info;
    329329                int sig = sigwaitinfo( &mask, &info );
    330 
    331                 if( sig < 0 ) {
    332                         //Error!
    333                         int err = errno;
    334                         switch( err ) {
    335                                 case EAGAIN :
    336                                 case EINTR :
    337                                         continue;
    338                         case EINVAL :
    339                                         abortf("Timeout was invalid.");
    340                                 default:
    341                                         abortf("Unhandled error %d", err);
    342                         }
    343                 }
    344330
    345331                // If another signal arrived something went wrong
  • src/libcfa/concurrency/thread

    r74bba15 raf58ee0  
    3636forall( dtype T | is_thread(T) )
    3737static inline coroutine_desc* get_coroutine(T & this) {
    38         return &get_thread(this)->self_cor;
     38        return &get_thread(this)->cor;
    3939}
    4040
    4141forall( dtype T | is_thread(T) )
    4242static inline monitor_desc* get_monitor(T & this) {
    43         return &get_thread(this)->self_mon;
     43        return &get_thread(this)->mon;
    4444}
    4545
    4646static inline coroutine_desc* get_coroutine(thread_desc * this) {
    47         return &this->self_cor;
     47        return &this->cor;
    4848}
    4949
    5050static inline monitor_desc* get_monitor(thread_desc * this) {
    51         return &this->self_mon;
     51        return &this->mon;
    5252}
    5353
  • src/libcfa/concurrency/thread.c

    r74bba15 raf58ee0  
    3333
    3434void ?{}(thread_desc& this) {
    35         (this.self_cor){};
    36         this.self_cor.name = "Anonymous Coroutine";
    37         this.self_mon.owner = &this;
    38         this.self_mon.recursion = 1;
    39         this.self_mon_p = &this.self_mon;
     35        (this.cor){};
     36        this.cor.name = "Anonymous Coroutine";
     37        this.mon.owner = &this;
     38        this.mon.recursion = 1;
    4039        this.next = NULL;
    4140
    42         (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 };
     41        this.current_monitors      = &this.mon;
     42        this.current_monitor_count = 1;
    4343}
    4444
    4545void ^?{}(thread_desc& this) {
    46         ^(this.self_cor){};
     46        ^(this.cor){};
    4747}
    4848
  • src/main.cc

    r74bba15 raf58ee0  
    239239                } // if
    240240
     241                // OPTPRINT( "Concurrency" )
     242                // Concurrency::applyKeywords( translationUnit );
     243
    241244                // add the assignment statement after the initialization of a type parameter
    242245                OPTPRINT( "validate" )
  • src/prelude/prelude.cf

    r74bba15 raf58ee0  
    4242_Bool                   ?--( _Bool & ),                         ?--( volatile _Bool & );
    4343unsigned char           ?++( unsigned char & ),                 ?++( volatile unsigned char & );
    44 signed short            ?++( signed short & ),                  ?++( volatile signed short & );
    45 signed short            ?--( signed short & ),                  ?--( volatile signed short & );
    46 unsigned short          ?++( unsigned short & ),                ?++( volatile unsigned short & );
    47 unsigned short          ?--( unsigned short & ),                ?--( volatile unsigned short & );
    4844signed int              ?++( signed int & ),                    ?++( volatile signed int & );
    4945signed int              ?--( signed int & ),                    ?--( volatile signed int & );
     
    9692
    9793_Bool                   ++?( _Bool & ),                         --?( _Bool & );
    98 signed short    ++?( signed short & ),                  --?( signed short & );
    9994signed int              ++?( signed int & ),                    --?( signed int & );
    100 unsigned short          ++?( unsigned int & ),                  --?( unsigned int & );
    101 unsigned int            ++?( unsigned short & ),                --?( unsigned short & );
     95unsigned int            ++?( unsigned int & ),                  --?( unsigned int & );
    10296signed long int         ++?( signed long int & ),               --?( signed long int & );
    10397unsigned long int       ++?( unsigned long int & ),             --?( unsigned long int & );
  • src/tests/Makefile.am

    r74bba15 raf58ee0  
    2222concurrent = yes
    2323quick_test += coroutine thread monitor
    24 concurrent_test = coroutine thread monitor multi-monitor sched-int-block sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statment preempt
     24concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
    2525else
    2626concurrent=no
     
    104104        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    105105
    106 sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@
    107         ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    108 
    109106gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@
    110107        ${CC} ${AM_CFLAGS} ${CFLAGS} -lgmp ${<} -o ${@}
  • src/tests/Makefile.in

    r74bba15 raf58ee0  
    320320@BUILD_CONCURRENCY_TRUE@concurrent = yes
    321321@BUILD_CONCURRENCY_FALSE@concurrent_test =
    322 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-block sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statment preempt
     322@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
    323323
    324324# applies to both programs
     
    856856        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    857857
    858 sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@
    859         ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}
    860 
    861858gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@
    862859        ${CC} ${AM_CFLAGS} ${CFLAGS} -lgmp ${<} -o ${@}
  • src/tests/sched-ext-parse.c

    r74bba15 raf58ee0  
    8080                16;
    8181        }
    82         or waitfor( f2, a, a ) {
     82        or waitfor( f1, a, a ) {
    8383                17;
    8484        }
  • src/tests/sched-ext.c

    r74bba15 raf58ee0  
    4545        acceptable.monitors      = &a;
    4646
    47         __waitfor_internal( 1, &acceptable );
     47        __accept_internal( 1, &acceptable );
    4848
    4949        sout | "Accepted" | endl;
Note: See TracChangeset for help on using the changeset viewer.