Changeset 5802a4f


Ignore:
Timestamp:
Dec 15, 2016, 4:16:52 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
66f8528
Parents:
9facf3b
Message:

remove assignment to polymorphic return values in Box

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r9facf3b r5802a4f  
    5454#include "Common/UniqueName.h"
    5555#include "Common/utility.h"
     56
     57#include "InitTweak/InitTweak.h"
    5658
    5759#include <ext/functional> // temporary
     
    113115                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    114116                        /// Stores assignment operators from assertion list in local map of assignment operations
    115                         void findTypeOps( const Type::ForallList &forall );
    116117                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    117118                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     
    121122                        ObjectDecl *makeTemporary( Type *type );
    122123
    123                         ScopedMap< std::string, DeclarationWithType* > assignOps;    ///< Currently known type variable assignment operators
    124                         ScopedMap< std::string, DeclarationWithType* > ctorOps;      ///< Currently known type variable constructors
    125                         ScopedMap< std::string, DeclarationWithType* > copyOps;      ///< Currently known type variable copy constructors
    126                         ScopedMap< std::string, DeclarationWithType* > dtorOps;      ///< Currently known type variable destructors
    127                         ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    128                         ResolvExpr::TypeMap< DeclarationWithType > scopedCtorOps;    ///< Currently known assignment operators
    129                         ResolvExpr::TypeMap< DeclarationWithType > scopedCopyOps;    ///< Currently known assignment operators
    130                         ResolvExpr::TypeMap< DeclarationWithType > scopedDtorOps;    ///< Currently known assignment operators
    131124                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    132125
     
    500493                Pass1::Pass1() : tempNamer( "_temp" ) {}
    501494
    502                 /// Returns T if the given declaration is a function with parameter (T*) for some TypeInstType T, NULL otherwise
    503                 TypeInstType *isTypeInstPtrFn( DeclarationWithType *decl ) {
    504                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    505                                 if ( funType->get_parameters().size() == 1 ) {
    506                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    507                                                 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    508                                                         return refType;
    509                                                 } // if
    510                                         } // if
    511                                 } // if
    512                         } // if
    513                         return 0;
    514                 }
    515 
    516                 /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise
    517                 TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) {
    518                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    519                                 if ( funType->get_parameters().size() == 2 ) {
    520                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    521                                                 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    522                                                         if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    523                                                                 if ( refType->get_name() == refType2->get_name() ) {
    524                                                                         return refType;
    525                                                                 } // if
    526                                                         } // if
    527                                                 } // if
    528                                         } // if
    529                                 } // if
    530                         } // if
    531                         return 0;
    532                 }
    533 
    534                 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    535                 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
    536                         return decl->get_name() == "?=?" ? isTypeInstPtrValFn( decl ) : 0;
    537                 }
    538 
    539                 /// Returns T if the given declaration is (*?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    540                 TypeInstType *isTypeInstCtor( DeclarationWithType *decl ) {
    541                         return decl->get_name() == "?{}" ? isTypeInstPtrFn( decl ) : 0;
    542                 }
    543 
    544                 /// Returns T if the given declaration is (*?{})(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    545                 TypeInstType *isTypeInstCopy( DeclarationWithType *decl ) {
    546                         return decl->get_name() == "?{}" ? isTypeInstPtrValFn( decl ) : 0;
    547                 }
    548 
    549                 /// Returns T if the given declaration is (*^?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    550                 TypeInstType *isTypeInstDtor( DeclarationWithType *decl ) {
    551                         return decl->get_name() == "^?{}" ? isTypeInstPtrFn( decl ) : 0;
    552                 }
    553 
    554                 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
    555                 /// NULL otherwise
    556                 Type *isNoCvPtrFn( DeclarationWithType *decl ) {
    557                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    558                                 if ( funType->get_parameters().size() == 1 ) {
    559                                         Type::Qualifiers defaultQualifiers;
    560                                         Type *paramType = funType->get_parameters().front()->get_type();
    561                                         if ( paramType->get_qualifiers() != defaultQualifiers ) return 0;
    562 
    563                                         if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType ) ) {
    564                                                 Type *baseType = pointerType->get_base();
    565                                                 if ( baseType->get_qualifiers() == defaultQualifiers ) {
    566                                                         return baseType;
    567                                                 } // if
    568                                         } // if
    569                                 } // if
    570                         } // if
    571                         return 0;
    572                 }
    573 
    574                 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
    575                 /// NULL otherwise
    576                 Type *isNoCvPtrValFn( DeclarationWithType *decl ) {
    577                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    578                                 if ( funType->get_parameters().size() == 2 ) {
    579                                         Type::Qualifiers defaultQualifiers;
    580                                         Type *paramType1 = funType->get_parameters().front()->get_type();
    581                                         if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
    582                                         Type *paramType2 = funType->get_parameters().back()->get_type();
    583                                         if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
    584 
    585                                         if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
    586                                                 Type *baseType1 = pointerType->get_base();
    587                                                 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
    588                                                 SymTab::Indexer dummy;
    589                                                 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
    590                                                         return baseType1;
    591                                                 } // if
    592                                         } // if
    593                                 } // if
    594                         } // if
    595                         return 0;
    596                 }
    597 
    598                 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    599                 /// Only picks assignments where neither parameter is cv-qualified
    600                 Type *isAssignment( DeclarationWithType *decl ) {
    601                         return decl->get_name() == "?=?" ? isNoCvPtrValFn( decl ) : 0;
    602                 }
    603 
    604                 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
    605                 /// Only picks ctors where the parameter is not cv-qualified
    606                 Type *isCtor( DeclarationWithType *decl ) {
    607                         return decl->get_name() == "?{}" ? isNoCvPtrFn( decl ) : 0;
    608                 }
    609 
    610                 /// returns T if the given declaration is: (*?{})(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    611                 /// Only picks copy constructors where neither parameter is cv-qualified
    612                 Type *isCopy( DeclarationWithType *decl ) {
    613                         return decl->get_name() == "?{}" ? isNoCvPtrValFn( decl ) : 0;
    614                 }
    615 
    616                 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
    617                 /// Only picks ctors where the parameter is not cv-qualified
    618                 Type *isDtor( DeclarationWithType *decl ) {
    619                         return decl->get_name() == "^?{}" ? isNoCvPtrFn( decl ) : 0;
    620                 }
    621 
    622                 void Pass1::findTypeOps( const Type::ForallList &forall ) {
    623                         // what if a nested function uses an assignment operator?
    624                         // assignOps.clear();
    625                         for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    626                                 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    627                                         std::string typeName;
    628                                         if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
    629                                                 assignOps[ typeInst->get_name() ] = *assert;
    630                                         } else if ( TypeInstType *typeInst = isTypeInstCtor( *assert ) ) {
    631                                                 ctorOps[ typeInst->get_name() ] = *assert;
    632                                         } else if ( TypeInstType *typeInst = isTypeInstCopy( *assert ) ) {
    633                                                 copyOps[ typeInst->get_name() ] = *assert;
    634                                         } else if ( TypeInstType *typeInst = isTypeInstDtor( *assert ) ) {
    635                                                 dtorOps[ typeInst->get_name() ] = *assert;
    636                                         } // if
    637                                 } // for
    638                         } // for
    639                 }
    640 
    641495                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    642                         // if this is a assignment function, put it in the map for this scope
    643                         if ( Type *paramType = isAssignment( functionDecl ) ) {
    644                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    645                                         scopedAssignOps.insert( paramType, functionDecl );
    646                                 }
    647                         } else if ( Type *paramType = isCtor( functionDecl ) ) {
    648                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    649                                         scopedCtorOps.insert( paramType, functionDecl );
    650                                 }
    651                         } else if ( Type *paramType = isCopy( functionDecl ) ) {
    652                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    653                                         scopedCopyOps.insert( paramType, functionDecl );
    654                                 }
    655                         } else if ( Type *paramType = isDtor( functionDecl ) ) {
    656                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    657                                         scopedDtorOps.insert( paramType, functionDecl );
    658                                 }
    659                         }
    660 
    661496                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    662497                                doBeginScope();
    663498                                scopeTyVars.beginScope();
    664                                 assignOps.beginScope();
    665                                 ctorOps.beginScope();
    666                                 copyOps.beginScope();
    667                                 dtorOps.beginScope();
    668499
    669500                                DeclarationWithType *oldRetval = retval;
     
    683514                                FunctionType *functionType = functionDecl->get_functionType();
    684515                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    685                                 findTypeOps( functionDecl->get_functionType()->get_forall() );
    686516
    687517                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    707537
    708538                                scopeTyVars.endScope();
    709                                 assignOps.endScope();
    710                                 ctorOps.endScope();
    711                                 copyOps.endScope();
    712                                 dtorOps.endScope();
    713539                                retval = oldRetval;
    714540                                doEndScope();
     
    811637                                Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
    812638                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
     639                                ++fnArg; // skip the return parameter in the argument list
    813640                        }
    814641
    815642                        // add type information args for presently unseen types in parameter list
    816643                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    817                                 VariableExpr *fnArgBase = getBaseVar( *fnArg );
    818                                 if ( ! fnArgBase ) continue; // xxx - previously had check for non-empty fnArgBase results
    819                                 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_result(), arg, exprTyVars, seenTypes );
     644                                if ( ! (*fnArg)->get_result() ) continue;
     645                                Type * argType = (*fnArg)->get_result();
     646                                passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes );
    820647                        }
    821648                }
     
    967794                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    968795                                        InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    969                                         assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
     796                                        if ( inferParam == appExpr->get_inferParams().end() ) {
     797                                                std::cerr << "looking for assertion: " << (*assert) << std::endl << appExpr << std::endl;
     798                                        }
     799                                        assertf( inferParam != appExpr->get_inferParams().end(), "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
    970800                                        Expression *newExpr = inferParam->second.expr->clone();
    971801                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     
    12951125
    12961126                        TyVarMap exprTyVars( TypeDecl::Data{} );
    1297                         makeTyVarMap( function, exprTyVars );
     1127                        makeTyVarMap( function, exprTyVars ); // xxx - should this take into account the variables already bound in scopeTyVars (i.e. remove them from exprTyVars?)
    12981128                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    1299                         Type *concRetType = appExpr->get_result();// ?: dynRetType; // xxx - is concRetType a good name?
     1129                        Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();// ?: dynRetType; // xxx - is concRetType a good name?
    13001130
    13011131                        if ( dynRetType ) {
    13021132                                ret = addDynRetParam( appExpr, function, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
    1303                         } else if ( needsAdapter( function, scopeTyVars ) ) {
     1133                        } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
     1134                                // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed.
     1135
    13041136                                // std::cerr << "needs adapter: ";
    13051137                                // printTyVarMap( std::cerr, scopeTyVars );
     
    13101142                        arg = appExpr->get_args().begin();
    13111143
    1312                         passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType
     1144                        passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
    13131145                        addInferredParams( appExpr, function, arg, exprTyVars );
    13141146
     
    13691201                }
    13701202
    1371                 /// Wraps a function declaration in a new pointer-to-function variable expression
    1372                 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
    1373                         // line below cloned from FixFunction.cc
    1374                         // xxx - functionObj is never added to a list of declarations...
    1375                         // alternatively, this function could return a new VariableExpr( functionDecl ) and change the result type of the new expression
    1376                         ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1377                                                                   new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1378                         functionObj->set_mangleName( functionDecl->get_mangleName() );
    1379                         functionObj->set_scopeLevel( functionDecl->get_scopeLevel() );
    1380                         return new VariableExpr( functionObj );
    1381                 }
    1382 
    1383                 /// Finds the operation declaration for a given type in one of the two maps
    1384                 DeclarationWithType* findOpForType( Type *formalType, const ScopedMap< std::string, DeclarationWithType* >& ops, ResolvExpr::TypeMap< DeclarationWithType >& scopedOps ) {
    1385                         if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1386                                 ScopedMap< std::string, DeclarationWithType *>::const_iterator opIt = ops.find( formalTypeInstType->get_name() );
    1387                                 return opIt == ops.end() ? 0 : opIt->second;
    1388                         } else {
    1389                                 return scopedOps.find( formalType );
    1390                         }
    1391                 }
    1392 
    1393                 /// Adds an assertion parameter to the application expression for the actual assertion declaration valued with the assert op
    1394                 void addAssertionFor( ApplicationExpr *appExpr, DeclarationWithType *actualDecl, DeclarationWithType *assertOp ) {
    1395                         appExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1396                                         = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) );
    1397                 }
    1398 
    13991203                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
     1204                        // maybe need access to the env when mutating the expr
     1205                        if ( Expression * expr = returnStmt->get_expr() ) {
     1206                                if ( expr->get_env() ) {
     1207                                        env = expr->get_env();
     1208                                }
     1209                        }
     1210
    14001211                        if ( retval && returnStmt->get_expr() ) {
    14011212                                assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
    1402                                 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    1403                                 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    1404                                 // by this point, a cast expr on a polymorphic return value is redundant
    1405                                 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
    1406                                         returnStmt->set_expr( castExpr->get_arg() );
    1407                                         returnStmt->get_expr()->set_env( castExpr->get_env() );
    1408                                         castExpr->set_env( 0 );
    1409                                         castExpr->set_arg( 0 );
    1410                                         delete castExpr;
    1411                                 } //while
    1412 
    1413                                 // find assignment operator for (polymorphic) return type
    1414                                 ApplicationExpr *assignExpr = 0;
    1415                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    1416                                         // find assignment operator for type variable
    1417                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    1418                                         if ( assignIter == assignOps.end() ) {
    1419                                                 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    1420                                         } // if
    1421                                         assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    1422                                 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    1423                                         // find assignment operator for generic type
    1424                                         DeclarationWithType *functionDecl = scopedAssignOps.find( refType );
    1425                                         if ( ! functionDecl ) {
    1426                                                 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    1427                                         }
    1428 
    1429                                         // wrap it up in an application expression
    1430                                         assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
    1431                                         assignExpr->set_env( env->clone() );
    1432 
    1433                                         // find each of its needed secondary assignment operators
    1434                                         std::list< Expression* > &tyParams = refType->get_parameters();
    1435                                         Type::ForallList &forallParams = functionDecl->get_type()->get_forall();
    1436                                         std::list< Expression* >::const_iterator tyIt = tyParams.begin();
    1437                                         Type::ForallList::const_iterator forallIt = forallParams.begin();
    1438                                         for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1439                                                 // Add appropriate mapping to assignment expression environment
    1440                                                 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    1441                                                 assert( formalTypeExpr && "type parameters must be type expressions" );
    1442                                                 Type *formalType = formalTypeExpr->get_type();
    1443                                                 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    1444 
    1445                                                 // skip non-otype parameters (ftype/dtype)
    1446                                                 // xxx - should this check whether the type is complete instead?
    1447                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    1448 
    1449                                                 // find otype operators for formal type
    1450                                                 DeclarationWithType *assertAssign = findOpForType( formalType, assignOps, scopedAssignOps );
    1451                                                 if ( ! assertAssign ) throw SemanticError( "No assignment operation found for ", formalType );
    1452 
    1453                                                 DeclarationWithType *assertCtor = findOpForType( formalType, ctorOps, scopedCtorOps );
    1454                                                 if ( ! assertCtor ) throw SemanticError( "No default constructor found for ", formalType );
    1455 
    1456                                                 DeclarationWithType *assertCopy = findOpForType( formalType, copyOps, scopedCopyOps );
    1457                                                 if ( ! assertCopy ) throw SemanticError( "No copy constructor found for ", formalType );
    1458 
    1459                                                 DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps );
    1460                                                 if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType );
    1461 
    1462                                                 // add inferred parameters for otype operators to assignment expression
    1463                                                 // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order
    1464                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1465                                                 assert( asserts.size() >= 4 && "Type param needs otype operator assertions" );
    1466 
    1467                                                 std::list< DeclarationWithType* >::iterator actualIt = asserts.begin();
    1468                                                 addAssertionFor( assignExpr, *actualIt, assertAssign );
    1469                                                 ++actualIt;
    1470                                                 addAssertionFor( assignExpr, *actualIt, assertCtor );
    1471                                                 ++actualIt;
    1472                                                 addAssertionFor( assignExpr, *actualIt, assertCopy );
    1473                                                 ++actualIt;
    1474                                                 addAssertionFor( assignExpr, *actualIt, assertDtor );
    1475 
    1476                                         }
    1477                                 }
    1478                                 assert( assignExpr );
    1479 
    1480                                 // replace return statement with appropriate assignment to out parameter
    1481                                 Expression *retParm = new NameExpr( retval->get_name() );
    1482                                 retParm->set_result( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    1483                                 assignExpr->get_args().push_back( retParm );
    1484                                 assignExpr->get_args().push_back( returnStmt->get_expr() );
    1485                                 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    1486                                 // } else {
    1487                                 //      useRetval = true;
    1488                                 //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
    1489                                 //      useRetval = false;
    1490                                 // } // if
     1213                                delete returnStmt->get_expr();
    14911214                                returnStmt->set_expr( 0 );
    14921215                        } else {
     
    15181241                void Pass1::doBeginScope() {
    15191242                        adapters.beginScope();
    1520                         scopedAssignOps.beginScope();
    1521                         scopedCtorOps.beginScope();
    1522                         scopedCopyOps.beginScope();
    1523                         scopedDtorOps.beginScope();
    15241243                }
    15251244
    15261245                void Pass1::doEndScope() {
    15271246                        adapters.endScope();
    1528                         scopedAssignOps.endScope();
    1529                         scopedCtorOps.endScope();
    1530                         scopedCopyOps.endScope();
    1531                         scopedDtorOps.endScope();
    15321247                }
    15331248
     
    15691284
    15701285                DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
    1571                         if ( ! LinkageSpec::isBuiltin( functionDecl->get_linkage() ) ) {
    1572                                 // std::cerr << "mutating function: " << functionDecl->get_name() << std::endl;
    1573                         }
    15741286                        functionDecl = safe_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl, functionDecl->get_functionType() ) );
    15751287                        FunctionType * ftype = functionDecl->get_functionType();
     
    18611573                                // replace member expression with pointer to base plus offset
    18621574                                UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1863                                 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
     1575                                Expression * aggr = memberExpr->get_aggregate()->clone();
     1576                                delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
     1577                                aggr->set_env( nullptr );
     1578                                fieldLoc->get_args().push_back( aggr );
    18641579                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
    18651580                                newMemberExpr = fieldLoc;
Note: See TracChangeset for help on using the changeset viewer.