Changeset a36eb2d


Ignore:
Timestamp:
Oct 25, 2021, 12:04:09 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
148ba7d
Parents:
da6396f
Message:

First translation of the Gen Init pass. Passed the tests.

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    rda6396f ra36eb2d  
    99// Author           : Rob Schluntz
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 23:15:10 2019
    13 // Update Count     : 184
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Oct 25 11:10:00 2021
     13// Update Count     : 185
    1414//
    1515#include "GenInit.h"
     
    2424#include "AST/Decl.hpp"
    2525#include "AST/Init.hpp"
     26#include "AST/Pass.hpp"
    2627#include "AST/Node.hpp"
    2728#include "AST/Stmt.hpp"
     
    294295        }
    295296
     297namespace {
     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,
     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 );
     319                storageClasses = decl->storage;
     320        }
     321
     322        const ast::DeclWithType * HoistArrayDimension_NoResolve_New::postvisit(
     323                        const ast::ObjectDecl * objectDecl ) {
     324                return mutate_field( objectDecl, &ast::ObjectDecl::type,
     325                                hoist( objectDecl->type ) );
     326        }
     327
     328        const ast::Type * HoistArrayDimension_NoResolve_New::hoist(
     329                        const ast::Type * type ) {
     330                static UniqueName dimensionName( "_array_dim" );
     331
     332                if ( !isInFunction() || storageClasses.is_static ) {
     333                        return type;
     334                }
     335
     336                if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
     337                        if ( nullptr == arrayType->dimension ) {
     338                                return type;
     339                        }
     340
     341                        if ( !Tuples::maybeImpure( arrayType->dimension ) ) {
     342                                return type;
     343                        }
     344
     345                        ast::ptr<ast::Type> dimType = ast::sizeType;
     346                        assert( dimType );
     347                        add_qualifiers( dimType, ast::CV::Qualifiers( ast::CV::Const ) );
     348
     349                        ast::ObjectDecl * arrayDimension = new ast::ObjectDecl(
     350                                arrayType->dimension->location,
     351                                dimensionName.newName(),
     352                                dimType,
     353                                new ast::SingleInit(
     354                                        arrayType->dimension->location,
     355                                        arrayType->dimension
     356                                )
     357                        );
     358
     359                        ast::ArrayType * mutType = ast::mutate( arrayType );
     360                        mutType->dimension = new ast::VariableExpr(
     361                                        arrayDimension->location, arrayDimension );
     362                        declsToAddBefore.push_back( arrayDimension );
     363
     364                        mutType->base = hoist( mutType->base );
     365                        return mutType;
     366                }
     367                return type;
     368        }
     369
     370        struct ReturnFixer_New final :
     371                        public ast::WithStmtsToAdd<>, ast::WithGuards {
     372                void previsit( const ast::FunctionDecl * decl );
     373                const ast::ReturnStmt * previsit( const ast::ReturnStmt * stmt );
     374        private:
     375                const ast::FunctionDecl * funcDecl = nullptr;
     376        };
     377
     378        void ReturnFixer_New::previsit( const ast::FunctionDecl * decl ) {
     379                GuardValue( funcDecl );
     380                funcDecl = decl;
     381        }
     382
     383        const ast::ReturnStmt * ReturnFixer_New::previsit(
     384                        const ast::ReturnStmt * stmt ) {
     385                auto & returns = funcDecl->returns;
     386                assert( returns.size() < 2 );
     387                // Hands off if the function returns a reference.
     388                // Don't allocate a temporary if the address is returned.
     389                if ( stmt->expr && 1 == returns.size() ) {
     390                        ast::ptr<ast::DeclWithType> retDecl = returns.front();
     391                        if ( isConstructable( retDecl->get_type() ) ) {
     392                                // Explicitly construct the return value using the return
     393                                // expression and the retVal object.
     394                                assertf( "" != retDecl->name,
     395                                        "Function %s has unnamed return value.\n",
     396                                        funcDecl->name.c_str() );
     397
     398                                auto retVal = retDecl.strict_as<ast::ObjectDecl>();
     399                                if ( auto varExpr = stmt->expr.as<ast::VariableExpr>() ) {
     400                                        // Check if the return statement is already set up.
     401                                        if ( varExpr->var == retVal ) return stmt;
     402                                }
     403                                ast::ptr<ast::Stmt> ctorStmt = genCtorDtor(
     404                                        retVal->location, "?{}", retVal, stmt->expr );
     405                                assertf( ctorStmt,
     406                                        "ReturnFixer: genCtorDtor returned nllptr: %s / %s",
     407                                        toString( retVal ).c_str(),
     408                                        toString( stmt->expr ).c_str() );
     409                                        stmtsToAddBefore.push_back( ctorStmt );
     410
     411                                // Return the retVal object.
     412                                ast::ReturnStmt * mutStmt = ast::mutate( stmt );
     413                                mutStmt->expr = new ast::VariableExpr(
     414                                        stmt->location, retDecl );
     415                                return mutStmt;
     416                        }
     417                }
     418                return stmt;
     419        }
     420
     421} // namespace
     422
     423        void genInit( ast::TranslationUnit & transUnit ) {
     424                ast::Pass<HoistArrayDimension_NoResolve_New>::run( transUnit );
     425                ast::Pass<ReturnFixer_New>::run( transUnit );
     426        }
     427
    296428        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    297429                PassVisitor<CtorDtor> ctordtor;
  • src/InitTweak/GenInit.h

    rda6396f ra36eb2d  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:31:19 2017
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Oct 22 16:08:00 2021
     13// Update Count     : 6
    1414//
    1515
     
    2727        /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes
    2828        void genInit( std::list< Declaration * > & translationUnit );
     29        void genInit( ast::TranslationUnit & translationUnit );
    2930
    3031        /// Converts return statements into copy constructor calls on the hidden return variable
  • src/main.cc

    rda6396f ra36eb2d  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Oct 12 15:41:00 2021
    13 // Update Count     : 652
     12// Last Modified On : Fri Oct 22 16:06:00 2021
     13// Update Count     : 653
    1414//
    1515
     
    336336                PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
    337337                PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
    338                 PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
    339338
    340339                CodeTools::fillLocations( translationUnit );
     
    349348                        forceFillCodeLocations( transUnit );
    350349
     350                        PASS( "Gen Init", InitTweak::genInit( transUnit ) );
    351351                        PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( transUnit ) );
    352352
     
    383383                        translationUnit = convert( move( transUnit ) );
    384384                } else {
     385                        PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
    385386                        PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) );
    386387
Note: See TracChangeset for help on using the changeset viewer.