Changeset fc1a3e2 for src/Virtual
- Timestamp:
- Apr 19, 2024, 2:36:52 PM (19 months ago)
- Branches:
- master
- Children:
- ba97ebf
- Parents:
- b9b6efb
- File:
-
- 1 edited
-
src/Virtual/VirtualDtor.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Virtual/VirtualDtor.cpp
rb9b6efb rfc1a3e2 28 28 29 29 struct CtorDtor { 30 FunctionDecl * dtorSetup; // dtor init routine to add after last dtor for a struct31 FunctionDecl * deleteFn;32 FunctionDecl * lastDtor; // pointer to last occurence of dtor to know where to insert after33 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) {} 35 35 }; 36 36 37 37 class CtorDtorTable { 38 unordered_map<const StructDecl *, CtorDtor> & structMap; 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 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 } 39 111 40 112 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) {} 115 115 }; 116 116 117 117 // generates the forward decl of virtual dtor setting routine and delete routine 118 118 // 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 120 120 // for dtor setters and delete fns (via table above) 121 121 struct 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/messages127 // gens the dtor fwd decl and dtor call in ctor128 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 reference133 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 instance137 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 message141 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 it145 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 ctor170 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() ), ExplicitCast241 )242 }243 )244 ));245 246 // put it all together into the complete function decl from above247 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 }, // params257 {},258 nullptr, // body259 { Storage::Static }, // storage260 Linkage::Cforall, // linkage261 {}, // attributes262 { 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 }, // params328 {},329 nullptr, // body330 { Storage::Static }, // storage331 Linkage::Cforall, // linkage332 {}, // attributes333 { 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 } 342 342 343 343 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) {} 346 346 }; 347 347 … … 349 349 // generates the trailing definitions of dtor setting routines for virtual dtors on messages and actors 350 350 // 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 352 352 // the last dtor defn which is found in prior pass 353 353 struct GenSetDtor : public ast::WithDeclsToAdd<> { 354 unordered_map<const StructDecl *, CtorDtor> & structDecls; // set of decls that inherit from virt dtor355 CtorDtorTable & torDecls;356 357 // handles adding the declaration of the dtor init routine after the last dtor detected358 void postvisit( const FunctionDecl * decl ) {359 if ( decl->name != "^?{}" || !decl->stmts || decl->params.size() != 1 ) return;360 361 // the one param should be a reference362 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 instance366 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 table372 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) {} 382 382 }; 383 383 384 384 void implementVirtDtors( TranslationUnit & translationUnit ) { 385 // unordered_map to collect all derived types and associated data386 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_dtor393 Pass<CollectStructDecls>::run( translationUnit, structDecls, virtualDtor );394 395 // second pass locates all dtor/ctor routines that need modifying or need fns inserted before/after396 Pass<GenFuncsCreateTables>::run( translationUnit, structDecls, torDecls, virtualDtor );397 398 // The third pass adds the forward decls needed to resolve circular defn problems399 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 ); 400 400 } 401 402 401 403 402 } // namespace Virtual
Note:
See TracChangeset
for help on using the changeset viewer.