Changeset 1ed9cb63 for src/InitTweak/GenInit.cc
- Timestamp:
- Oct 27, 2021, 5:15:41 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 40a64f78
- Parents:
- 8a039be (diff), c600df1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r8a039be r1ed9cb63 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Dec 13 23:15:10 201913 // Update Count : 18 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Oct 25 13:53:00 2021 13 // Update Count : 186 14 14 // 15 15 #include "GenInit.h" … … 24 24 #include "AST/Decl.hpp" 25 25 #include "AST/Init.hpp" 26 #include "AST/Pass.hpp" 26 27 #include "AST/Node.hpp" 27 28 #include "AST/Stmt.hpp" … … 294 295 } 295 296 297 namespace { 298 299 # warning Remove the _New suffix after the conversion is complete. 300 struct HoistArrayDimension_NoResolve_New final : 301 public ast::WithDeclsToAdd<>, public ast::WithShortCircuiting, 302 public ast::WithGuards, public ast::WithConstTranslationUnit, 303 public ast::WithVisitorRef<HoistArrayDimension_NoResolve_New> { 304 void previsit( const ast::ObjectDecl * decl ); 305 const ast::DeclWithType * postvisit( const ast::ObjectDecl * decl ); 306 // Do not look for objects inside there declarations (and type). 307 void previsit( const ast::AggregateDecl * ) { visit_children = false; } 308 void previsit( const ast::NamedTypeDecl * ) { visit_children = false; } 309 void previsit( const ast::FunctionType * ) { visit_children = false; } 310 311 const ast::Type * hoist( const ast::Type * type ); 312 313 ast::Storage::Classes storageClasses; 314 }; 315 316 void HoistArrayDimension_NoResolve_New::previsit( 317 const ast::ObjectDecl * decl ) { 318 GuardValue( storageClasses ) = decl->storage; 319 } 320 321 const ast::DeclWithType * HoistArrayDimension_NoResolve_New::postvisit( 322 const ast::ObjectDecl * objectDecl ) { 323 return mutate_field( objectDecl, &ast::ObjectDecl::type, 324 hoist( objectDecl->type ) ); 325 } 326 327 const ast::Type * HoistArrayDimension_NoResolve_New::hoist( 328 const ast::Type * type ) { 329 static UniqueName dimensionName( "_array_dim" ); 330 331 if ( !isInFunction() || storageClasses.is_static ) { 332 return type; 333 } 334 335 if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) { 336 if ( nullptr == arrayType->dimension ) { 337 return type; 338 } 339 340 if ( !Tuples::maybeImpure( arrayType->dimension ) ) { 341 return type; 342 } 343 344 ast::ptr<ast::Type> dimType = transUnit().global.sizeType; 345 assert( dimType ); 346 add_qualifiers( dimType, ast::CV::Qualifiers( ast::CV::Const ) ); 347 348 ast::ObjectDecl * arrayDimension = new ast::ObjectDecl( 349 arrayType->dimension->location, 350 dimensionName.newName(), 351 dimType, 352 new ast::SingleInit( 353 arrayType->dimension->location, 354 arrayType->dimension 355 ) 356 ); 357 358 ast::ArrayType * mutType = ast::mutate( arrayType ); 359 mutType->dimension = new ast::VariableExpr( 360 arrayDimension->location, arrayDimension ); 361 declsToAddBefore.push_back( arrayDimension ); 362 363 mutType->base = hoist( mutType->base ); 364 return mutType; 365 } 366 return type; 367 } 368 369 struct ReturnFixer_New final : 370 public ast::WithStmtsToAdd<>, ast::WithGuards { 371 void previsit( const ast::FunctionDecl * decl ); 372 const ast::ReturnStmt * previsit( const ast::ReturnStmt * stmt ); 373 private: 374 const ast::FunctionDecl * funcDecl = nullptr; 375 }; 376 377 void ReturnFixer_New::previsit( const ast::FunctionDecl * decl ) { 378 GuardValue( funcDecl ) = decl; 379 } 380 381 const ast::ReturnStmt * ReturnFixer_New::previsit( 382 const ast::ReturnStmt * stmt ) { 383 auto & returns = funcDecl->returns; 384 assert( returns.size() < 2 ); 385 // Hands off if the function returns a reference. 386 // Don't allocate a temporary if the address is returned. 387 if ( stmt->expr && 1 == returns.size() ) { 388 ast::ptr<ast::DeclWithType> retDecl = returns.front(); 389 if ( isConstructable( retDecl->get_type() ) ) { 390 // Explicitly construct the return value using the return 391 // expression and the retVal object. 392 assertf( "" != retDecl->name, 393 "Function %s has unnamed return value.\n", 394 funcDecl->name.c_str() ); 395 396 auto retVal = retDecl.strict_as<ast::ObjectDecl>(); 397 if ( auto varExpr = stmt->expr.as<ast::VariableExpr>() ) { 398 // Check if the return statement is already set up. 399 if ( varExpr->var == retVal ) return stmt; 400 } 401 ast::ptr<ast::Stmt> ctorStmt = genCtorDtor( 402 retVal->location, "?{}", retVal, stmt->expr ); 403 assertf( ctorStmt, 404 "ReturnFixer: genCtorDtor returned nllptr: %s / %s", 405 toString( retVal ).c_str(), 406 toString( stmt->expr ).c_str() ); 407 stmtsToAddBefore.push_back( ctorStmt ); 408 409 // Return the retVal object. 410 ast::ReturnStmt * mutStmt = ast::mutate( stmt ); 411 mutStmt->expr = new ast::VariableExpr( 412 stmt->location, retDecl ); 413 return mutStmt; 414 } 415 } 416 return stmt; 417 } 418 419 } // namespace 420 421 void genInit( ast::TranslationUnit & transUnit ) { 422 ast::Pass<HoistArrayDimension_NoResolve_New>::run( transUnit ); 423 ast::Pass<ReturnFixer_New>::run( transUnit ); 424 } 425 296 426 void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) { 297 427 PassVisitor<CtorDtor> ctordtor;
Note: See TracChangeset
for help on using the changeset viewer.