Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rce8c12f r62423350  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:13:47 2017
    13 // Update Count     : 71
     12// Last Modified On : Wed Jun 21 17:35:05 2017
     13// Update Count     : 74
    1414//
    1515
     
    2020#include <unordered_map>
    2121#include <unordered_set>
     22
    2223#include "InitTweak.h"
    2324#include "GenInit.h"
    2425#include "FixInit.h"
    2526#include "FixGlobalInit.h"
     27#include "CodeGen/GenType.h"  // for warning/error messages
     28#include "Common/PassVisitor.h"
     29#include "GenPoly/DeclMutator.h"
     30#include "GenPoly/PolyMutator.h"
    2631#include "ResolvExpr/Resolver.h"
    2732#include "ResolvExpr/typeops.h"
     33#include "SymTab/Autogen.h"
     34#include "SymTab/Indexer.h"
     35#include "SynTree/AddStmtVisitor.h"
     36#include "SynTree/Attribute.h"
    2837#include "SynTree/Declaration.h"
    29 #include "SynTree/Type.h"
    3038#include "SynTree/Expression.h"
    31 #include "SynTree/Attribute.h"
    32 #include "SynTree/Statement.h"
    3339#include "SynTree/Initializer.h"
    3440#include "SynTree/Mutator.h"
    35 #include "SymTab/Indexer.h"
    36 #include "SymTab/Autogen.h"
    37 #include "GenPoly/PolyMutator.h"
    38 #include "GenPoly/DeclMutator.h"
    39 #include "SynTree/AddStmtVisitor.h"
    40 #include "CodeGen/GenType.h"  // for warning/error messages
     41#include "SynTree/Statement.h"
     42#include "SynTree/Type.h"
    4143#include "Tuples/Tuples.h"
    4244
     
    5456                typedef std::unordered_map< int, int > UnqCount;
    5557
    56                 class InsertImplicitCalls final : public GenPoly::PolyMutator {
     58                class InsertImplicitCalls : public WithTypeSubstitution {
    5759                public:
    5860                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
     
    6163
    6264                        InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
    63                         typedef GenPoly::PolyMutator Parent;
    64                         using Parent::mutate;
    65                         virtual Expression * mutate( ApplicationExpr * appExpr ) override;
    66                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     65
     66                        Expression * postmutate( ApplicationExpr * appExpr );
     67                        void premutate( StmtExpr * stmtExpr );
    6768
    6869                        // collects environments for relevant nodes
     
    103104                        typedef AddStmtVisitor Parent;
    104105                        using Parent::visit;
    105                         typedef std::set< ObjectDecl * > ObjectSet;
     106                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
     107                        typedef std::list< ObjectDecl * > ObjectSet;
    106108                        virtual void visit( CompoundStmt *compoundStmt ) override;
    107109                        virtual void visit( DeclStmt *stmt ) override;
    108110
    109111                        // don't go into other functions
    110                         virtual void visit( FunctionDecl *decl ) override {}
     112                        virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {}
    111113
    112114                  protected:
     
    115117
    116118                // debug
    117                 struct printSet {
    118                         typedef ObjDeclCollector::ObjectSet ObjectSet;
    119                         printSet( const ObjectSet & objs ) : objs( objs ) {}
     119                template<typename ObjectSet>
     120                struct PrintSet {
     121                        PrintSet( const ObjectSet & objs ) : objs( objs ) {}
    120122                        const ObjectSet & objs;
    121123                };
    122                 std::ostream & operator<<( std::ostream & out, const printSet & set) {
     124                template<typename ObjectSet>
     125                PrintSet<ObjectSet> printSet( const ObjectSet & objs ) { return PrintSet<ObjectSet>( objs ); }
     126                template<typename ObjectSet>
     127                std::ostream & operator<<( std::ostream & out, const PrintSet<ObjectSet> & set) {
    123128                        out << "{ ";
    124129                        for ( ObjectDecl * obj : set.objs ) {
     
    190195                };
    191196
    192                 class FixInit final : public GenPoly::PolyMutator {
     197                class FixInit : public WithStmtsToAdd {
    193198                  public:
    194199                        /// expand each object declaration to use its constructor after it is declared.
    195200                        static void fixInitializers( std::list< Declaration * > &translationUnit );
    196201
    197                         typedef GenPoly::PolyMutator Parent;
    198                         using Parent::mutate;
    199                         virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override;
     202                        DeclarationWithType * postmutate( ObjectDecl *objDecl );
    200203
    201204                        std::list< Declaration * > staticDtorDecls;
     
    300303        namespace {
    301304                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    302                         InsertImplicitCalls inserter( envMap );
     305                        PassVisitor<InsertImplicitCalls> inserter( envMap );
    303306                        mutateAll( translationUnit, inserter );
    304307                }
     
    310313
    311314                void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
    312                         FixInit fixer;
     315                        PassVisitor<FixInit> fixer;
    313316
    314317                        // can't use mutateAll, because need to insert declarations at top-level
     
    318321                                try {
    319322                                        *i = maybeMutate( *i, fixer );
    320                                         translationUnit.splice( i, fixer.staticDtorDecls );
     323                                        translationUnit.splice( i, fixer.pass.staticDtorDecls );
    321324                                } catch( SemanticError &e ) {
    322325                                        e.set_location( (*i)->location );
     
    350353                }
    351354
    352                 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    353                         appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );
     355                Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
    354356                        assert( appExpr );
    355357
     
    393395                }
    394396
    395                 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {
     397                void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
    396398                        assert( env );
    397399                        envMap[stmtExpr] = env;
    398                         return Parent::mutate( stmtExpr );
    399400                }
    400401
    401402                bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
    402                         return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
     403                        return dynamic_cast< VarArgsType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
    403404                }
    404405
     
    696697                }
    697698
    698                 DeclarationWithType *FixInit::mutate( ObjectDecl *objDecl ) {
    699                         // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init
    700                         // is removed from the ObjectDecl
    701                         objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) );
     699                DeclarationWithType *FixInit::postmutate( ObjectDecl *objDecl ) {
     700                        // since this removes the init field from objDecl, it must occur after children are mutated (i.e. postmutate)
    702701                        if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    703702                                // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     
    729728                                                // static bool __objName_uninitialized = true
    730729                                                BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    731                                                 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators );
     730                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
    732731                                                ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
    733732                                                isUninitializedVar->fixUniqueId();
     
    736735                                                UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
    737736                                                setTrue->get_args().push_back( new VariableExpr( isUninitializedVar ) );
    738                                                 setTrue->get_args().push_back( new ConstantExpr( Constant( boolType->clone(), "0" ) ) );
     737                                                setTrue->get_args().push_back( new ConstantExpr( Constant::from_int( 0 ) ) );
    739738
    740739                                                // generate body of if
     
    750749
    751750                                                Statement * dtor = ctorInit->get_dtor();
    752                                                 objDecl->set_init( NULL );
    753                                                 ctorInit->set_ctor( NULL );
     751                                                objDecl->set_init( nullptr );
     752                                                ctorInit->set_ctor( nullptr );
    754753                                                ctorInit->set_dtor( nullptr );
    755754                                                if ( dtor ) {
     
    804803                                                } else {
    805804                                                        stmtsToAddAfter.push_back( ctor );
    806                                                         objDecl->set_init( NULL );
    807                                                         ctorInit->set_ctor( NULL );
     805                                                        objDecl->set_init( nullptr );
     806                                                        ctorInit->set_ctor( nullptr );
    808807                                                }
    809808                                        } // if
    810809                                } else if ( Initializer * init = ctorInit->get_init() ) {
    811810                                        objDecl->set_init( init );
    812                                         ctorInit->set_init( NULL );
     811                                        ctorInit->set_init( nullptr );
    813812                                } else {
    814813                                        // no constructor and no initializer, which is okay
    815                                         objDecl->set_init( NULL );
     814                                        objDecl->set_init( nullptr );
    816815                                } // if
    817816                                delete ctorInit;
     
    821820
    822821                void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
    823                         std::set< ObjectDecl * > prevVars = curVars;
     822                        ObjectSet prevVars = curVars;
    824823                        Parent::visit( compoundStmt );
    825824                        curVars = prevVars;
     
    829828                        // keep track of all variables currently in scope
    830829                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    831                                 curVars.insert( objDecl );
     830                                curVars.push_back( objDecl );
    832831                        } // if
    833832                        Parent::visit( stmt );
     
    896895                        Parent::visit( compoundStmt );
    897896
    898                         // add destructors for the current scope that we're exiting
     897                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
     898                        // causes unreachable code warnings
    899899                        std::list< Statement * > & statements = compoundStmt->get_kids();
    900                         insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) );
     900                        if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) {
     901                                insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) );
     902                        }
    901903                        reverseDeclOrder.pop_front();
    902904                }
    903905
    904                 void InsertDtors::visit( ReturnStmt * returnStmt ) {
     906                void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
    905907                        // return exits all scopes, so dump destructors for all scopes
    906908                        for ( OrderedDecls & od : reverseDeclOrder ) {
     
    941943                        )
    942944                        if ( ! diff.empty() ) {
     945                                // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
     946                                std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
     947
    943948                                // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
    944949                                OrderedDecls ordered;
    945950                                for ( OrderedDecls & rdo : reverseDeclOrder ) {
    946951                                        // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
    947                                         copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );
     952                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    948953                                } // for
    949954                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
Note: See TracChangeset for help on using the changeset viewer.