Changeset ec42ff2e


Ignore:
Timestamp:
Sep 6, 2018, 10:49:09 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2f86ddf
Parents:
7ba1324
Message:

Add SplitExpressions? pass to wrap top-level expressions in CompoundStmts?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r7ba1324 rec42ff2e  
    234234                        Expression * postmutate( ConstructorExpr * ctorExpr );
    235235                };
     236
     237                struct SplitExpressions : public WithShortCircuiting, public WithTypeSubstitution, public WithStmtsToAdd {
     238                        /// add CompoundStmts around top-level expressions so that temporaries are destroyed in the correct places.
     239                        static void split( std::list< Declaration * > &translationUnit );
     240
     241                        Statement * postmutate( ExprStmt * stmt );
     242                        void premutate( TupleAssignExpr * expr );
     243                };
    236244        } // namespace
    237245
     
    244252
    245253                UnqCount unqCount;
     254
     255                // must happen before ResolveCopyCtors because temporaries have to be inserted into the correct scope
     256                SplitExpressions::split( translationUnit );
    246257
    247258                InsertImplicitCalls::insert( translationUnit );
     
    312323
    313324                        return dtorFunc;
     325                }
     326
     327                void SplitExpressions::split( std::list< Declaration * > & translationUnit ) {
     328                        PassVisitor<SplitExpressions> splitter;
     329                        mutateAll( translationUnit, splitter );
    314330                }
    315331
     
    364380                }
    365381
    366                 namespace {
    367                         // Relatively simple structural comparison for expressions, needed to determine
    368                         // if two expressions are "the same" (used to determine if self assignment occurs)
    369                         struct StructuralChecker {
    370                                 Expression * stripCasts( Expression * expr ) {
    371                                         // this might be too permissive. It's possible that only particular casts are relevant.
    372                                         while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
    373                                                 expr = cast->arg;
    374                                         }
    375                                         return expr;
    376                                 }
    377 
    378                                 void previsit( Expression * ) {
    379                                         // anything else does not qualify
    380                                         isSimilar = false;
    381                                 }
    382 
    383                                 template<typename T>
    384                                 T * cast( Expression * node ) {
    385                                         // all expressions need to ignore casts, so this bit has been factored out
    386                                         return dynamic_cast< T * >( stripCasts( node ) );
    387                                 }
    388 
    389                                 // ignore casts
    390                                 void previsit( CastExpr * ) {}
    391 
    392                                 void previsit( MemberExpr * memExpr ) {
    393                                         if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
    394                                                 if ( otherMember->member == memExpr->member ) {
    395                                                         other = otherMember->aggregate;
    396                                                         return;
    397                                                 }
    398                                         }
    399                                         isSimilar = false;
    400                                 }
    401 
    402                                 void previsit( VariableExpr * varExpr ) {
    403                                         if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
    404                                                 if ( otherVar->var == varExpr->var ) {
    405                                                         return;
    406                                                 }
    407                                         }
    408                                         isSimilar = false;
    409                                 }
    410 
    411                                 void previsit( AddressExpr * ) {
    412                                         if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
    413                                                 other = addrExpr->arg;
     382                Statement * SplitExpressions::postmutate( ExprStmt * stmt ) {
     383                        // wrap each top-level ExprStmt in a block so that destructors for argument and return temporaries are destroyed
     384                        // in the correct places
     385                        CompoundStmt * ret = new CompoundStmt( { stmt } );
     386                        return ret;
     387                }
     388
     389                void SplitExpressions::premutate( TupleAssignExpr * ) {
     390                        // don't do this within TupleAssignExpr, since it is already broken up into multiple expressions
     391                        visit_children = false;
     392                }
     393
     394                // Relatively simple structural comparison for expressions, needed to determine
     395                // if two expressions are "the same" (used to determine if self assignment occurs)
     396                struct StructuralChecker {
     397                        Expression * stripCasts( Expression * expr ) {
     398                                // this might be too permissive. It's possible that only particular casts are relevant.
     399                                while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
     400                                        expr = cast->arg;
     401                                }
     402                                return expr;
     403                        }
     404
     405                        void previsit( Expression * ) {
     406                                // anything else does not qualify
     407                                isSimilar = false;
     408                        }
     409
     410                        template<typename T>
     411                        T * cast( Expression * node ) {
     412                                // all expressions need to ignore casts, so this bit has been factored out
     413                                return dynamic_cast< T * >( stripCasts( node ) );
     414                        }
     415
     416                        // ignore casts
     417                        void previsit( CastExpr * ) {}
     418
     419                        void previsit( MemberExpr * memExpr ) {
     420                                if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
     421                                        if ( otherMember->member == memExpr->member ) {
     422                                                other = otherMember->aggregate;
    414423                                                return;
    415424                                        }
    416                                         isSimilar = false;
    417                                 }
    418 
    419                                 Expression * other = nullptr;
    420                                 bool isSimilar = true;
    421                         };
    422 
    423                         bool structurallySimilar( Expression * e1, Expression * e2 ) {
    424                                 PassVisitor<StructuralChecker> checker;
    425                                 checker.pass.other = e2;
    426                                 e1->accept( checker );
    427                                 return checker.pass.isSimilar;
    428                         }
     425                                }
     426                                isSimilar = false;
     427                        }
     428
     429                        void previsit( VariableExpr * varExpr ) {
     430                                if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
     431                                        if ( otherVar->var == varExpr->var ) {
     432                                                return;
     433                                        }
     434                                }
     435                                isSimilar = false;
     436                        }
     437
     438                        void previsit( AddressExpr * ) {
     439                                if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
     440                                        other = addrExpr->arg;
     441                                        return;
     442                                }
     443                                isSimilar = false;
     444                        }
     445
     446                        Expression * other = nullptr;
     447                        bool isSimilar = true;
     448                };
     449
     450                bool structurallySimilar( Expression * e1, Expression * e2 ) {
     451                        PassVisitor<StructuralChecker> checker;
     452                        checker.pass.other = e2;
     453                        e1->accept( checker );
     454                        return checker.pass.isSimilar;
    429455                }
    430456
     
    535561                                        // so that the object isn't changed inside of the polymorphic function
    536562                                        if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return;
     563                                        // xxx - leaking tmp
    537564                                }
    538565                        }
Note: See TracChangeset for help on using the changeset viewer.