Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Virtual/VirtualDtor.cpp

    rfc1a3e2 r37273c8  
    2828
    2929struct CtorDtor {
    30         FunctionDecl * dtorSetup;  // dtor init routine to add after last dtor for a struct
    31         FunctionDecl * deleteFn;
    32         FunctionDecl * lastDtor;    // pointer to last occurence of dtor to know where to insert after
    33 
    34         CtorDtor() : dtorSetup(nullptr), deleteFn(nullptr), lastDtor(nullptr) {}
     30    FunctionDecl * dtorSetup;  // dtor init routine to add after last dtor for a struct
     31    FunctionDecl * deleteFn;
     32    FunctionDecl * lastDtor;    // pointer to last occurence of dtor to know where to insert after
     33
     34    CtorDtor() : dtorSetup(nullptr), deleteFn(nullptr), lastDtor(nullptr) {}
    3535};
    3636
    3737class CtorDtorTable {
    38         unordered_map<const StructDecl *, CtorDtor> & structMap;
    39 
    40 public:
    41         // if dtor is last dtor for this decl return the routine to add afterwards
    42         // otherwise return nullptr
    43         FunctionDecl * getToAddLater( const StructDecl * decl, FunctionDecl * dtor, FunctionDecl ** retDeleteFn ) {
    44                 auto iter = structMap.find( decl );
    45                 if ( iter == structMap.end() || iter->second.lastDtor != dtor ) return nullptr; // check if this is needed
    46                 *retDeleteFn = iter->second.deleteFn;
    47                 return iter->second.dtorSetup;
     38    unordered_map<const StructDecl *, CtorDtor> & structMap;
     39
     40  public:
     41    // if dtor is last dtor for this decl return the routine to add afterwards
     42    // otherwise return nullptr
     43    FunctionDecl * getToAddLater( const StructDecl * decl, FunctionDecl * dtor, FunctionDecl ** retDeleteFn ) {
     44        auto iter = structMap.find( decl );
     45        if ( iter == structMap.end() || iter->second.lastDtor != dtor ) return nullptr; // check if this is needed
     46        *retDeleteFn = iter->second.deleteFn;
     47        return iter->second.dtorSetup;
     48    }
     49
     50    // return if the dtorSetup field has been defined for this decl
     51    bool inTable( const StructDecl * decl ) {
     52        auto iter = structMap.find( decl );
     53        return iter->second.dtorSetup != nullptr;
     54    }
     55
     56    void addLater( const StructDecl * decl, FunctionDecl * dtorSetup, FunctionDecl * deleteFn ) {
     57        auto iter = structMap.find( decl );
     58        iter->second.dtorSetup = dtorSetup;
     59        iter->second.deleteFn = deleteFn;
     60    }
     61
     62    void addDtor( const StructDecl * decl, FunctionDecl * dtor ) {
     63        auto iter = structMap.find( decl );
     64        iter->second.lastDtor = dtor;
     65    }
     66
     67    CtorDtorTable( unordered_map<const StructDecl *, CtorDtor> & structMap ) : structMap(structMap) {}
     68};
     69
     70struct CollectStructDecls : public ast::WithGuards {
     71    unordered_map<const StructDecl *, CtorDtor> & structDecls;
     72    StructDecl * parentDecl;
     73    bool insideStruct = false;
     74    bool namedDecl = false;
     75
     76    const StructDecl ** virtualDtor;
     77
     78    // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
     79    void previsit( const StructDecl * decl ) {
     80        if ( !decl->body ) return;
     81        if( decl->name == "virtual_dtor" ) {
     82            structDecls.emplace( make_pair( decl, CtorDtor() ) );
     83            *virtualDtor = decl;
     84        } else {
     85            GuardValue(insideStruct);
     86            insideStruct = true;
     87            parentDecl = mutate( decl );
     88        }
    4889        }
    4990
    50         // return if the dtorSetup field has been defined for this decl
    51         bool inTable( const StructDecl * decl ) {
    52                 auto iter = structMap.find( decl );
    53                 return iter->second.dtorSetup != nullptr;
     91    // this catches structs of the form:
     92    //     struct derived_type { virtual_dtor a; };
     93    // since they should be:
     94    //     struct derived_type { inline virtual_dtor; };
     95    void previsit ( const ObjectDecl * decl ) {
     96        if ( insideStruct && ! decl->name.empty() ) {
     97            GuardValue(namedDecl);
     98            namedDecl = true;
     99        }
     100    }
     101
     102    // this collects the derived actor and message struct decl ptrs
     103    void postvisit( const StructInstType * node ) {
     104        if ( ! *virtualDtor ) return;
     105        if ( insideStruct && !namedDecl ) {
     106            auto structIter = structDecls.find( node->aggr() );   
     107            if ( structIter != structDecls.end() )
     108                structDecls.emplace( make_pair( parentDecl, CtorDtor() ) );
     109        }
    54110        }
    55111
    56         void addLater( const StructDecl * decl, FunctionDecl * dtorSetup, FunctionDecl * deleteFn ) {
    57                 auto iter = structMap.find( decl );
    58                 iter->second.dtorSetup = dtorSetup;
    59                 iter->second.deleteFn = deleteFn;
    60         }
    61 
    62         void addDtor( const StructDecl * decl, FunctionDecl * dtor ) {
    63                 auto iter = structMap.find( decl );
    64                 iter->second.lastDtor = dtor;
    65         }
    66 
    67         CtorDtorTable( unordered_map<const StructDecl *, CtorDtor> & structMap ) : structMap(structMap) {}
    68 };
    69 
    70 struct CollectStructDecls : public ast::WithGuards {
    71         unordered_map<const StructDecl *, CtorDtor> & structDecls;
    72         StructDecl * parentDecl;
    73         bool insideStruct = false;
    74         bool namedDecl = false;
    75 
    76         const StructDecl ** virtualDtor;
    77 
    78         // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
    79         void previsit( const StructDecl * decl ) {
    80                 if ( !decl->body ) return;
    81                 if( decl->name == "virtual_dtor" ) {
    82                         structDecls.emplace( make_pair( decl, CtorDtor() ) );
    83                         *virtualDtor = decl;
    84                 } else {
    85                         GuardValue(insideStruct);
    86                         insideStruct = true;
    87                         parentDecl = mutate( decl );
    88                 }
    89         }
    90 
    91         // this catches structs of the form:
    92         //     struct derived_type { virtual_dtor a; };
    93         // since they should be:
    94         //     struct derived_type { inline virtual_dtor; };
    95         void previsit ( const ObjectDecl * decl ) {
    96                 if ( insideStruct && ! decl->name.empty() ) {
    97                         GuardValue(namedDecl);
    98                         namedDecl = true;
    99                 }
    100         }
    101 
    102         // this collects the derived actor and message struct decl ptrs
    103         void postvisit( const StructInstType * node ) {
    104                 if ( ! *virtualDtor ) return;
    105                 if ( insideStruct && !namedDecl ) {
    106                         auto structIter = structDecls.find( node->aggr() );
    107                         if ( structIter != structDecls.end() )
    108                                 structDecls.emplace( make_pair( parentDecl, CtorDtor() ) );
    109                 }
    110         }
    111 
    112112  public:
    113         CollectStructDecls( unordered_map<const StructDecl *, CtorDtor> & structDecls, const StructDecl ** virtualDtor ):
    114                 structDecls( structDecls ), virtualDtor(virtualDtor) {}
     113    CollectStructDecls( unordered_map<const StructDecl *, CtorDtor> & structDecls, const StructDecl ** virtualDtor ):
     114        structDecls( structDecls ), virtualDtor(virtualDtor) {}
    115115};
    116116
    117117// generates the forward decl of virtual dtor setting routine and delete routine
    118118// generates the call to the virtual dtor routine in each appropriate ctor
    119 // collects data needed for next pass that does the circular defn resolution
     119// collects data needed for next pass that does the circular defn resolution 
    120120//     for dtor setters and delete fns (via table above)
    121121struct GenFuncsCreateTables : public ast::WithDeclsToAdd<> {
    122         unordered_map<const StructDecl *, CtorDtor> & structDecls;
    123         CtorDtorTable & torDecls;
    124         const StructDecl ** virtualDtor;
    125 
    126         // collects the dtor info for actors/messages
    127         // gens the dtor fwd decl and dtor call in ctor
    128         void previsit( const FunctionDecl * decl ) {
    129                 if ( (decl->name != "?{}" && decl->name != "^?{}") || decl->params.size() == 0
    130                         || !decl->stmts || (decl->name == "^?{}" && decl->params.size() != 1)) return;
    131 
    132                 // the first param should be a reference
    133                 const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
    134                 if ( !ref ) return;
    135 
    136                 // the reference should be to a struct instance
    137                 const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
    138                 if ( !instType ) return;
    139 
    140                 // return if not ctor/dtor for an actor or message
    141                 auto structIter = structDecls.find( instType->aggr() );
    142                 if ( structIter == structDecls.end() ) return;
    143 
    144                 // If first param not named we need to name it to use it
    145                 if ( decl->params.at(0)->name == "" )
    146                         mutate( decl->params.at(0).get() )->name = "__CFA_Virt_Dtor_param";
    147 
    148                 if ( decl->name == "^?{}") {
    149                         torDecls.addDtor( structIter->first, mutate( decl ) );
    150 
    151                         CompoundStmt * dtorBody = mutate( decl->stmts.get() );
    152                         // Adds the following to the start of any actor/message dtor:
    153                         //  __CFA_dtor_shutdown( this );
    154                         dtorBody->push_front(
    155                                 new IfStmt( decl->location,
    156                                         new UntypedExpr (
    157                                                 decl->location,
    158                                                 new NameExpr( decl->location, "__CFA_dtor_shutdown" ),
    159                                                 {
    160                                                         new NameExpr( decl->location, decl->params.at(0)->name )
    161                                                 }
    162                                         ),
    163                                         new ReturnStmt( decl->location, nullptr )
    164                                 )
    165                         );
    166                         return;
    167                 }
    168 
    169                 // not dtor by this point so must be ctor
    170                 CompoundStmt * ctorBody = mutate( decl->stmts.get() );
    171                 // Adds the following to the end of any actor/message ctor:
    172                 //  __CFA_set_dtor( this );
    173                 ctorBody->push_back( new ExprStmt(
    174                         decl->location,
    175                         new UntypedExpr (
    176                                 decl->location,
    177                                 new NameExpr( decl->location, "__CFA_set_dtor" ),
    178                                 {
    179                                         new NameExpr( decl->location, decl->params.at(0)->name )
    180                                 }
    181                         )
    182                 ));
    183 
    184                 if ( torDecls.inTable( structIter->first ) ) return;
    185 
    186                 // Generates the following:
    187                 // void __CFA_set_dtor( Derived_type & this ){
    188                 //     void (*__my_dtor)( Derived_type & ) = ^?{};
    189                 //     this.__virtual_dtor = (void (*)( Base_type & ))__my_dtor;
    190                 //     this.__virtual_obj_start = (void *)(&this);
    191                 // }
    192                 CompoundStmt * setDtorBody = new CompoundStmt( decl->location );
    193 
    194                 // Function type is: (void (*)(Derived_type &))
    195                 FunctionType * derivedDtor = new FunctionType();
    196                 derivedDtor->params.push_back( ast::deepCopy( ref ) );
    197 
    198                 // Generates:
    199                 //      void (*__my_dtor)( Derived_type & ) = ^?{};
    200                 setDtorBody->push_back( new DeclStmt(
    201                         decl->location,
    202                         new ObjectDecl(
    203                                 decl->location,
    204                                 "__my_dtor",
    205                                 new PointerType( derivedDtor ),
    206                                 new SingleInit( decl->location, new NameExpr( decl->location, "^?{}" ) )
    207                         )
    208                 ));
    209 
    210                 // Function type is: (void (*)( Base_type & ))
    211                 FunctionType * baseDtor = new FunctionType();
    212                 baseDtor->params.push_back( new ReferenceType( new StructInstType( *virtualDtor ) ) );
    213 
    214                 // Generates:
    215                 //     __CFA_set_virt_dtor( this, (void (*)( Base_type & ))__my_dtor )
    216                 setDtorBody->push_back( new ExprStmt(
    217                         decl->location,
    218                         new UntypedExpr (
    219                                 decl->location,
    220                                 new NameExpr( decl->location, "__CFA_set_virt_dtor" ),
    221                                 {
    222                                         new NameExpr( decl->location, "this" ),
    223                                         new CastExpr( decl->location, new NameExpr( decl->location, "__my_dtor" ), new PointerType( baseDtor ), ExplicitCast )
    224                                 }
    225                         )
    226                 ));
    227 
    228                 // Generates:
    229                 //     __CFA_set_virt_start( (void *)(&this) );
    230                 setDtorBody->push_back( new ExprStmt(
    231                         decl->location,
    232                         new UntypedExpr (
    233                                 decl->location,
    234                                 new NameExpr( decl->location, "__CFA_set_virt_start" ),
    235                                 {
    236                                         new NameExpr( decl->location, "this" ),
    237                                         new CastExpr(
    238                                                 decl->location,
    239                                                 new AddressExpr( decl->location, new NameExpr( decl->location, "this" )),
    240                                                 new PointerType( new ast::VoidType() ), ExplicitCast
    241                                                 )
    242                                 }
    243                         )
    244                 ));
    245 
    246                 // put it all together into the complete function decl from above
    247                 FunctionDecl * setDtorFunction = new FunctionDecl(
    248                         decl->location,
    249                         "__CFA_set_dtor",
    250                         {
    251                                 new ObjectDecl(
    252                                         decl->location,
    253                                         "this",
    254                                         ast::deepCopy( ref )
    255                                 ),
    256                         },                      // params
    257                         {},
    258                         nullptr,               // body
    259                         { Storage::Static },    // storage
    260                         Linkage::Cforall,       // linkage
    261                         {},                     // attributes
    262                         { Function::Inline }
    263                 );
    264 
    265                 declsToAddBefore.push_back( ast::deepCopy( setDtorFunction ) );
    266 
    267                 setDtorFunction->stmts = setDtorBody;
    268 
    269                 // The following generates the following specialized delete routine:
    270                 // static inline void delete( derived_type * ptr ) {
    271                 //     if ( ptr )
    272                 //         ^(*ptr){};
    273                 //     __CFA_virt_free( *ptr );
    274                 // }
    275                 CompoundStmt * deleteFnBody = new CompoundStmt( decl->location );
    276 
    277                 // Generates:
    278                 //     if ( ptr )
    279                 //         ^(*ptr){};
    280                 deleteFnBody->push_back(
    281                         new IfStmt(
    282                                 decl->location,
    283                                 UntypedExpr::createCall(
    284                                         decl->location,
    285                                         "?!=?",
    286                                         {
    287                                                 new NameExpr( decl->location, "ptr" ),
    288                                                 ConstantExpr::null( decl->location, new PointerType( ast::deepCopy( instType ) ) )
    289                                         }
    290                                 ),
    291                                 new ExprStmt(
    292                                         decl->location,
    293                                         UntypedExpr::createCall(
    294                                                 decl->location,
    295                                                 "^?{}",
    296                                                 {
    297                                                         UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
    298                                                 }
    299                                         )
    300                                 )
    301                         )
    302                 );
    303 
    304                 // Generates:
    305                 //     __CFA_virt_free( *ptr );
    306                 deleteFnBody->push_back( new ExprStmt(
    307                                 decl->location,
    308                                 UntypedExpr::createCall(
    309                                         decl->location,
    310                                         "__CFA_virt_free",
    311                                         {
    312                                                 UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
    313                                         }
    314                                 )
    315                         )
    316                 );
    317 
    318                 FunctionDecl * deleteFn = new FunctionDecl(
    319                         decl->location,
    320                         "delete",
    321                         {
    322                                 new ObjectDecl(
    323                                         decl->location,
    324                                         "ptr",
    325                                         new PointerType( ast::deepCopy( instType ) )
    326                                 ),
    327                         },                      // params
    328                         {},
    329                         nullptr,               // body
    330                         { Storage::Static },    // storage
    331                         Linkage::Cforall,       // linkage
    332                         {},                     // attributes
    333                         { Function::Inline }
    334                 );
    335 
    336                 declsToAddBefore.push_back( ast::deepCopy( deleteFn ) );
    337 
    338                 deleteFn->stmts = deleteFnBody;
    339 
    340                 torDecls.addLater( structIter->first, setDtorFunction, deleteFn );
    341         }
     122    unordered_map<const StructDecl *, CtorDtor> & structDecls;
     123    CtorDtorTable & torDecls;
     124    const StructDecl ** virtualDtor;
     125
     126    // collects the dtor info for actors/messages
     127    // gens the dtor fwd decl and dtor call in ctor
     128    void previsit( const FunctionDecl * decl ) {
     129        if ( (decl->name != "?{}" && decl->name != "^?{}") || decl->params.size() == 0
     130            || !decl->stmts || (decl->name == "^?{}" && decl->params.size() != 1)) return;
     131
     132        // the first param should be a reference
     133        const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
     134        if ( !ref ) return;
     135
     136        // the reference should be to a struct instance
     137        const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
     138        if ( !instType ) return;
     139
     140        // return if not ctor/dtor for an actor or message
     141        auto structIter = structDecls.find( instType->aggr() );
     142        if ( structIter == structDecls.end() ) return;
     143
     144        // If first param not named we need to name it to use it
     145        if ( decl->params.at(0)->name == "" )
     146            mutate( decl->params.at(0).get() )->name = "__CFA_Virt_Dtor_param";
     147
     148        if ( decl->name == "^?{}") {
     149            torDecls.addDtor( structIter->first, mutate( decl ) );
     150
     151            CompoundStmt * dtorBody = mutate( decl->stmts.get() );
     152            // Adds the following to the start of any actor/message dtor:
     153            //  __CFA_dtor_shutdown( this );
     154            dtorBody->push_front(
     155                new IfStmt( decl->location,
     156                    new UntypedExpr (
     157                        decl->location,
     158                        new NameExpr( decl->location, "__CFA_dtor_shutdown" ),
     159                        {
     160                            new NameExpr( decl->location, decl->params.at(0)->name )
     161                        }
     162                    ),
     163                    new ReturnStmt( decl->location, nullptr )
     164                )
     165            );
     166            return;
     167        }
     168
     169        // not dtor by this point so must be ctor
     170        CompoundStmt * ctorBody = mutate( decl->stmts.get() );
     171        // Adds the following to the end of any actor/message ctor:
     172        //  __CFA_set_dtor( this );
     173        ctorBody->push_back( new ExprStmt(
     174            decl->location,
     175            new UntypedExpr (
     176                decl->location,
     177                new NameExpr( decl->location, "__CFA_set_dtor" ),
     178                {
     179                    new NameExpr( decl->location, decl->params.at(0)->name )
     180                }
     181            )
     182        ));
     183       
     184        if ( torDecls.inTable( structIter->first ) ) return;
     185
     186        // Generates the following:
     187        // void __CFA_set_dtor( Derived_type & this ){
     188        //     void (*__my_dtor)( Derived_type & ) = ^?{};
     189        //     this.__virtual_dtor = (void (*)( Base_type & ))__my_dtor;
     190        //     this.__virtual_obj_start = (void *)(&this);
     191        // }
     192        CompoundStmt * setDtorBody = new CompoundStmt( decl->location );
     193
     194        // Function type is: (void (*)(Derived_type &))
     195        FunctionType * derivedDtor = new FunctionType();
     196        derivedDtor->params.push_back( ast::deepCopy( ref ) );
     197
     198        // Generates:
     199        //      void (*__my_dtor)( Derived_type & ) = ^?{};
     200        setDtorBody->push_back( new DeclStmt(
     201            decl->location,
     202            new ObjectDecl(
     203                decl->location,
     204                "__my_dtor",
     205                new PointerType( derivedDtor ),
     206                new SingleInit( decl->location, new NameExpr( decl->location, "^?{}" ) )
     207            )
     208        ));
     209
     210        // Function type is: (void (*)( Base_type & ))
     211        FunctionType * baseDtor = new FunctionType();
     212        baseDtor->params.push_back( new ReferenceType( new StructInstType( *virtualDtor ) ) );
     213
     214        // Generates:
     215        //     __CFA_set_virt_dtor( this, (void (*)( Base_type & ))__my_dtor )
     216        setDtorBody->push_back( new ExprStmt(
     217            decl->location,
     218            new UntypedExpr (
     219                decl->location,
     220                new NameExpr( decl->location, "__CFA_set_virt_dtor" ),
     221                {
     222                    new NameExpr( decl->location, "this" ),
     223                    new CastExpr( decl->location, new NameExpr( decl->location, "__my_dtor" ), new PointerType( baseDtor ), ExplicitCast )
     224                }
     225            )
     226        ));
     227
     228        // Generates:
     229        //     __CFA_set_virt_start( (void *)(&this) );
     230        setDtorBody->push_back( new ExprStmt(
     231            decl->location,
     232            new UntypedExpr (
     233                decl->location,
     234                new NameExpr( decl->location, "__CFA_set_virt_start" ),
     235                {
     236                    new NameExpr( decl->location, "this" ),
     237                    new CastExpr(
     238                        decl->location,
     239                        new AddressExpr( decl->location, new NameExpr( decl->location, "this" )),
     240                        new PointerType( new ast::VoidType() ), ExplicitCast
     241                        )
     242                }
     243            )
     244        ));
     245
     246        // put it all together into the complete function decl from above
     247        FunctionDecl * setDtorFunction = new FunctionDecl(
     248            decl->location,
     249            "__CFA_set_dtor",
     250            {
     251                new ObjectDecl(
     252                    decl->location,
     253                    "this",
     254                    ast::deepCopy( ref )
     255                ),
     256            },                      // params
     257            {},
     258            nullptr,               // body
     259            { Storage::Static },    // storage
     260            Linkage::Cforall,       // linkage
     261            {},                     // attributes
     262            { Function::Inline }
     263        );
     264
     265        declsToAddBefore.push_back( ast::deepCopy( setDtorFunction ) );
     266
     267        setDtorFunction->stmts = setDtorBody;
     268
     269        // The following generates the following specialized delete routine:
     270        // static inline void delete( derived_type * ptr ) {
     271        //     if ( ptr )
     272        //         ^(*ptr){};
     273        //     __CFA_virt_free( *ptr );
     274        // }
     275        CompoundStmt * deleteFnBody = new CompoundStmt( decl->location );
     276
     277        // Generates:
     278        //     if ( ptr )
     279        //         ^(*ptr){};
     280        deleteFnBody->push_back(
     281            new IfStmt(
     282                decl->location,
     283                UntypedExpr::createCall(
     284                    decl->location,
     285                    "?!=?",
     286                    {
     287                        new NameExpr( decl->location, "ptr" ),
     288                        ConstantExpr::null( decl->location, new PointerType( ast::deepCopy( instType ) ) )
     289                    }
     290                ),
     291                new ExprStmt(
     292                    decl->location,
     293                    UntypedExpr::createCall(
     294                        decl->location,
     295                        "^?{}",
     296                        {
     297                            UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
     298                        }
     299                    )
     300                )
     301            )
     302        );
     303
     304        // Generates:
     305        //     __CFA_virt_free( *ptr );
     306        deleteFnBody->push_back( new ExprStmt(
     307                decl->location,
     308                UntypedExpr::createCall(
     309                    decl->location,
     310                    "__CFA_virt_free",
     311                    {
     312                        UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
     313                    }
     314                )
     315            )
     316        );
     317
     318        FunctionDecl * deleteFn = new FunctionDecl(
     319            decl->location,
     320            "delete",
     321            {
     322                new ObjectDecl(
     323                    decl->location,
     324                    "ptr",
     325                    new PointerType( ast::deepCopy( instType ) )
     326                ),
     327            },                      // params
     328            {},
     329            nullptr,               // body
     330            { Storage::Static },    // storage
     331            Linkage::Cforall,       // linkage
     332            {},                     // attributes
     333            { Function::Inline }
     334        );
     335
     336        declsToAddBefore.push_back( ast::deepCopy( deleteFn ) );
     337
     338        deleteFn->stmts = deleteFnBody;
     339
     340        torDecls.addLater( structIter->first, setDtorFunction, deleteFn );
     341    }
    342342
    343343  public:
    344         GenFuncsCreateTables( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls, const StructDecl ** virtualDtor ):
    345         structDecls(structDecls), torDecls(torDecls), virtualDtor(virtualDtor) {}
     344    GenFuncsCreateTables( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls, const StructDecl ** virtualDtor ):
     345    structDecls(structDecls), torDecls(torDecls), virtualDtor(virtualDtor) {}
    346346};
    347347
     
    349349// generates the trailing definitions of dtor setting routines for virtual dtors on messages and actors
    350350// generates the function defns of __CFA_set_dtor
    351 // separate pass is needed since  __CFA_set_dtor needs to be defined after
     351// separate pass is needed since  __CFA_set_dtor needs to be defined after 
    352352//   the last dtor defn which is found in prior pass
    353353struct GenSetDtor : public ast::WithDeclsToAdd<> {
    354         unordered_map<const StructDecl *, CtorDtor> & structDecls; // set of decls that inherit from virt dtor
    355         CtorDtorTable & torDecls;
    356 
    357         // handles adding the declaration of the dtor init routine after the last dtor detected
    358         void postvisit( const FunctionDecl * decl ) {
    359                 if ( decl->name != "^?{}" || !decl->stmts || decl->params.size() != 1 ) return;
    360 
    361                 // the one param should be a reference
    362                 const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
    363                 if ( !ref ) return;
    364 
    365                 // the reference should be to a struct instance
    366                 const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
    367                 if ( !instType ) return;
    368 
    369                 FunctionDecl * deleteRtn;
    370 
    371                 // returns nullptr if not in table
    372                 FunctionDecl * maybeAdd = torDecls.getToAddLater( instType->aggr(), mutate( decl ), &deleteRtn );
    373                 if ( maybeAdd ) {
    374                         declsToAddAfter.push_back( maybeAdd );
    375                         declsToAddAfter.push_back( deleteRtn );
    376                 }
    377         }
    378 
    379 public:
    380         GenSetDtor( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls ):
    381                 structDecls(structDecls), torDecls(torDecls) {}
     354    unordered_map<const StructDecl *, CtorDtor> & structDecls; // set of decls that inherit from virt dtor
     355    CtorDtorTable & torDecls;
     356
     357    // handles adding the declaration of the dtor init routine after the last dtor detected
     358    void postvisit( const FunctionDecl * decl ) {
     359        if ( decl->name != "^?{}" || !decl->stmts || decl->params.size() != 1 ) return;
     360
     361        // the one param should be a reference
     362        const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
     363        if ( !ref ) return;
     364
     365        // the reference should be to a struct instance
     366        const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
     367        if ( !instType ) return;
     368
     369        FunctionDecl * deleteRtn;
     370
     371        // returns nullptr if not in table
     372        FunctionDecl * maybeAdd = torDecls.getToAddLater( instType->aggr(), mutate( decl ), &deleteRtn );
     373        if ( maybeAdd ) {
     374            declsToAddAfter.push_back( maybeAdd );
     375            declsToAddAfter.push_back( deleteRtn );
     376        }
     377    }
     378
     379  public:
     380    GenSetDtor( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls ):
     381        structDecls(structDecls), torDecls(torDecls) {}
    382382};
    383383
    384384void implementVirtDtors( TranslationUnit & translationUnit ) {
    385         // unordered_map to collect all derived types and associated data
    386         unordered_map<const StructDecl *, CtorDtor> structDecls;
    387         CtorDtorTable torDecls( structDecls );
    388 
    389         const StructDecl * virtualDtorPtr = nullptr;
    390         const StructDecl ** virtualDtor = &virtualDtorPtr;
    391 
    392         // first pass collects all structs that inherit from virtual_dtor
    393         Pass<CollectStructDecls>::run( translationUnit, structDecls, virtualDtor );
    394 
    395         // second pass locates all dtor/ctor routines that need modifying or need fns inserted before/after
    396         Pass<GenFuncsCreateTables>::run( translationUnit, structDecls, torDecls, virtualDtor );
    397 
    398         // The third pass adds the forward decls needed to resolve circular defn problems
    399         Pass<GenSetDtor>::run( translationUnit, structDecls, torDecls );
     385    // unordered_map to collect all derived types and associated data
     386    unordered_map<const StructDecl *, CtorDtor> structDecls;
     387    CtorDtorTable torDecls( structDecls );
     388
     389    const StructDecl * virtualDtorPtr = nullptr;
     390    const StructDecl ** virtualDtor = &virtualDtorPtr;
     391
     392    // first pass collects all structs that inherit from virtual_dtor
     393    Pass<CollectStructDecls>::run( translationUnit, structDecls, virtualDtor );
     394
     395    // second pass locates all dtor/ctor routines that need modifying or need fns inserted before/after
     396    Pass<GenFuncsCreateTables>::run( translationUnit, structDecls, torDecls, virtualDtor );
     397
     398    // The third pass adds the forward decls needed to resolve circular defn problems
     399    Pass<GenSetDtor>::run( translationUnit, structDecls, torDecls );
    400400}
     401
    401402
    402403} // namespace Virtual
Note: See TracChangeset for help on using the changeset viewer.