Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r4318107 rbd85400  
    7373                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
    7474                        Expression *makeOffsetArray( StructInstType *type );
    75                         /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
    76                         void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
    7775                        /// passes extra type parameters into a polymorphic function application
    78                         void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     76                        void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7977                        /// wraps a function application with a new temporary for the out-parameter return value
    8078                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
     
    400398                }
    401399
    402                 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    403                         Type *polyBase = hasPolyBase( parmType, exprTyVars );
    404                         if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    405                                 std::string sizeName = sizeofName( polyBase );
    406                                 if ( seenTypes.count( sizeName ) ) return;
    407 
    408                                 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
    409                                 arg++;
    410                                 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    411                                 arg++;
    412                                 if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    413                                         if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    414                                                 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
    415                                                 arg++;
    416                                         } else {
    417                                                 throw SemanticError( "Cannot pass non-struct type for generic struct" );
    418                                         }
    419                                 }
    420 
    421                                 seenTypes.insert( sizeName );
    422                         }
    423                 }
    424 
    425                 void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     400                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    426401                        // pass size/align for type variables
    427402                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
     
    449424                        std::list< Expression* >::const_iterator fnArg = arg;
    450425                        std::set< std::string > seenTypes; //< names for generic types we've seen
    451 
    452                         // a polymorphic return type may need to be added to the argument list
    453                         if ( polyRetType ) {
    454                                 Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
    455                                 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    456                         }
    457                        
    458                         // add type information args for presently unseen types in parameter list
    459426                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    460                                 VariableExpr *fnArgBase = getBaseVar( *fnArg );
    461                                 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
    462                                 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
     427                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars );
     428                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     429                                        std::string sizeName = sizeofName( polyBase );
     430                                        if ( seenTypes.count( sizeName ) ) continue;
     431
     432                                        VariableExpr *fnArgBase = getBaseVar( *fnArg );
     433                                        assert( fnArgBase && ! fnArgBase->get_results().empty() );
     434                                        Type *argBaseType = fnArgBase->get_results().front();
     435                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     436                                        arg++;
     437                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
     438                                        arg++;
     439                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     440                                                if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
     441                                                        arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     442                                                        arg++;
     443                                                } else {
     444                                                        throw SemanticError( "Cannot pass non-struct type for generic struct" );
     445                                                }
     446                                        }
     447
     448                                        seenTypes.insert( sizeName );
     449                                }
    463450                        }
    464451                }
     
    483470                        ObjectDecl *newObj = makeTemporary( retType->clone() );
    484471                        Expression *paramExpr = new VariableExpr( newObj );
    485 
    486                         // If the type of the temporary is not polymorphic, box temporary by taking its address;
    487                         // otherwise the temporary is already boxed and can be used directly.
     472                        // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
     473                        // temporary is already boxed and can be used directly.
    488474                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
    489475                                paramExpr = new AddressExpr( paramExpr );
     
    534520                        assert( env );
    535521                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    536                         // add out-parameter for return value   
    537522                        return addRetParam( appExpr, function, concrete, arg );
    538523                }
     
    557542                        assert( ! arg->get_results().empty() );
    558543                        if ( isPolyType( param, exprTyVars ) ) {
    559                                 if ( isPolyType( arg->get_results().front() ) ) {
    560                                         // if the argument's type is polymorphic, we don't need to box again!
     544                                if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {
     545                                        // if the argument's type is a type parameter, we don't need to box again!
    561546                                        return;
    562547                                } else if ( arg->get_results().front()->get_isLvalue() ) {
     
    637622                        assert( arg );
    638623                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
    639                                 if ( ! isPolyType( arg->get_type() ) ) {
     624                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    640625                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    641626                                        deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     
    932917                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    933918
    934                         TyVarMap exprTyVars;
    935                         makeTyVarMap( function, exprTyVars );
    936                         ReferenceToType *polyRetType = 0;
    937 
    938                         if ( polyRetType = isPolyRet( function ) ) {
    939                                 ret = addPolyRetParam( appExpr, function, polyRetType, arg );
     919                        if ( ReferenceToType *polyType = isPolyRet( function ) ) {
     920                                ret = addPolyRetParam( appExpr, function, polyType, arg );
    940921                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    941922                                // std::cerr << "needs adapter: ";
     
    949930                        arg = appExpr->get_args().begin();
    950931
    951                         passTypeVars( appExpr, polyRetType, arg, exprTyVars );
     932                        TyVarMap exprTyVars;
     933                        makeTyVarMap( function, exprTyVars );
     934
     935                        passTypeVars( appExpr, arg, exprTyVars );
    952936                        addInferredParams( appExpr, function, arg, exprTyVars );
    953937
     
    1008992                }
    1009993
    1010                 /// Wraps a function declaration in a new pointer-to-function variable expression
    1011                 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
    1012                         // line below cloned from FixFunction.cc
    1013                         ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1014                                                                   new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1015                         functionObj->set_mangleName( functionDecl->get_mangleName() );
    1016                         return new VariableExpr( functionObj );
    1017                 }
    1018                
    1019994                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    1020995                        if ( retval && returnStmt->get_expr() ) {
     
    10321007
    10331008                                // find assignment operator for (polymorphic) return type
    1034                                 ApplicationExpr *assignExpr = 0;
     1009                                DeclarationWithType *assignDecl = 0;
    10351010                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    1036                                         // find assignment operator for type variable
    10371011                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10381012                                        if ( assignIter == assignOps.end() ) {
    10391013                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10401014                                        } // if
    1041                                         assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     1015                                        assignDecl = assignIter->second;
    10421016                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    1043                                         // find assignment operator for generic type
    10441017                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10451018                                        if ( assignIter == scopedAssignOps.end() ) {
    10461019                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10471020                                        }
    1048 
    1049                                         // wrap it up in an application expression
    10501021                                        DeclarationWithType *functionDecl = assignIter->second;
    1051                                         assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
    1052                                         assignExpr->set_env( env->clone() );
    1053 
    1054                                         // find each of its needed secondary assignment operators
    1055                                         std::list< Expression* > &tyParams = refType->get_parameters();
    1056                                         std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
    1057                                         std::list< Expression* >::const_iterator tyIt = tyParams.begin();
    1058                                         std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    1059                                         for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1060                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
    1061 
    1062                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1063                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1064                                                 DeclarationWithType *actualDecl = asserts.front();
    1065                                                 ReferenceToType *actualType = isAssignment( actualDecl );
    1066                                                 assert( actualType && "First assertion of type with assertions should be assignment operator" );
    1067                                                 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    1068                                                 assert( formalTypeExpr && "type parameters must be type expressions" );
    1069                                                 Type *formalType = formalTypeExpr->get_type();
    1070                                                 assignExpr->get_env()->add( actualType->get_name(), formalType );
    1071                                                
    1072                                                 DeclarationWithType *assertAssign = 0;
    1073                                                 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1074                                                         std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
    1075                                                         if ( assertAssignIt == assignOps.end() ) {
    1076                                                                 throw SemanticError( "No assignment operation found for ", formalTypeInstType );
    1077                                                         }
    1078                                                         assertAssign = assertAssignIt->second;
    1079                                                         //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
    1080                                                 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
    1081                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
    1082                                                         if ( assertAssignIt == scopedAssignOps.end() ) {
    1083                                                                 throw SemanticError( "No assignment operation found for ", formalReferenceType );
    1084                                                         }
    1085                                                         assertAssign = assertAssignIt->second;
    1086                                                 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
    1087                                                
    1088 
    1089                                                 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1090                                                         = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
    1091                                         }
     1022                                        // line below cloned from FixFunction.cc
     1023                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1024                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1025                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
    10921026                                }
    1093                                 assert( assignExpr );
     1027                                assert( assignDecl );
    10941028
    10951029                                // replace return statement with appropriate assignment to out parameter
     1030                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10961031                                Expression *retParm = new NameExpr( retval->get_name() );
    10971032                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    12451180                        }
    12461181
    1247                         // add size/align for generic parameter types to parameter list
     1182                        // add size/align for generic types to parameter list
    12481183                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    12491184                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     
    13601295
    13611296                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1362                                         if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty()
    1363                                              || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1297                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
    13641298                                        else continue;
    13651299                                } else return i;
     
    14071341                        if ( ! objectType ) return memberExpr;
    14081342
    1409                         Expression *newMemberExpr = 0;
    14101343                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    14111344                                // look up offset index
     
    14171350                                fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
    14181351                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
    1419                                 newMemberExpr = fieldLoc;
    1420                         } else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
     1352
     1353                                delete memberExpr;
     1354                                return fieldLoc;
     1355                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
    14211356                                // union members are all at offset zero, so build appropriately-dereferenced variable
    1422                                 newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth );
     1357                                Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
     1358                                delete memberExpr;
     1359                                return derefdVar;
    14231360                        } else return memberExpr;
    1424                         assert( newMemberExpr );
    1425 
    1426                         // wrap pointer members in appropriate cast
    1427                         if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) {
    1428                                 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) );
    1429                                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    1430                                 derefExpr->get_args().push_back( ptrCastExpr );
    1431                                 newMemberExpr = derefExpr;
    1432                         }
    1433 
    1434                         delete memberExpr;
    1435                         return newMemberExpr;
    14361361                }
    14371362
     
    14541379                                delete offsetofExpr;
    14551380                                return offsetInd;
    1456                         } else if ( dynamic_cast< UnionInstType* >( ty ) ) {
     1381                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
    14571382                                // all union members are at offset zero
    14581383                                delete offsetofExpr;
Note: See TracChangeset for help on using the changeset viewer.