Changes in src/InitTweak/GenInit.cc [c600df1:09867ec]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
rc600df1 r09867ec 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Oct 25 13:53:00 202113 // Update Count : 18 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 23:15:10 2019 13 // Update Count : 184 14 14 // 15 15 #include "GenInit.h" … … 24 24 #include "AST/Decl.hpp" 25 25 #include "AST/Init.hpp" 26 #include "AST/Pass.hpp"27 26 #include "AST/Node.hpp" 28 27 #include "AST/Stmt.hpp" … … 295 294 } 296 295 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->dimension355 )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 return391 // 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 } // namespace420 421 void genInit( ast::TranslationUnit & transUnit ) {422 ast::Pass<HoistArrayDimension_NoResolve_New>::run( transUnit );423 ast::Pass<ReturnFixer_New>::run( transUnit );424 }425 426 296 void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) { 427 297 PassVisitor<CtorDtor> ctordtor;
Note:
See TracChangeset
for help on using the changeset viewer.