Ignore:
Timestamp:
Apr 19, 2024, 2:36:52 PM (3 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
ba97ebf
Parents:
b9b6efb
Message:

Style update. Focused on indentation and trailing whitespace.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Virtual/VirtualDtor.cpp

    rb9b6efb rfc1a3e2  
    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;
     38        unordered_map<const StructDecl *, CtorDtor> & structMap;
     39
     40public:
     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                }
     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        }
    39111
    40112  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 
    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 
    112   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
     379public:
     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 
    402401
    403402} // namespace Virtual
Note: See TracChangeset for help on using the changeset viewer.