Changeset a172972 for src/GenPoly


Ignore:
Timestamp:
Feb 23, 2016, 11:20:39 AM (10 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
ae42f2a
Parents:
7528ba1 (diff), 6ce67ce (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ctor

Conflicts:

src/ResolvExpr/Resolver.cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r7528ba1 ra172972  
    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 );
    7577                        /// passes extra type parameters into a polymorphic function application
    76                         void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     78                        void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7779                        /// wraps a function application with a new temporary for the out-parameter return value
    7880                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
     
    399401                }
    400402
    401                 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     403                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
     404                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     405                        if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     406                                std::string sizeName = sizeofName( polyBase );
     407                                if ( seenTypes.count( sizeName ) ) return;
     408
     409                                arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     410                                arg++;
     411                                arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
     412                                arg++;
     413                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     414                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
     415                                                arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     416                                                arg++;
     417                                        } else {
     418                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     419                                        }
     420                                }
     421
     422                                seenTypes.insert( sizeName );
     423                        }
     424                }
     425
     426                void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    402427                        // pass size/align for type variables
    403428                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
     
    425450                        std::list< Expression* >::const_iterator fnArg = arg;
    426451                        std::set< std::string > seenTypes; //< names for generic types we've seen
     452
     453                        // a polymorphic return type may need to be added to the argument list
     454                        if ( polyRetType ) {
     455                                Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
     456                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
     457                        }
     458                       
     459                        // add type information args for presently unseen types in parameter list
    427460                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    428                                 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars );
    429                                 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    430                                         std::string sizeName = sizeofName( polyBase );
    431                                         if ( seenTypes.count( sizeName ) ) continue;
    432 
    433                                         VariableExpr *fnArgBase = getBaseVar( *fnArg );
    434                                         assert( fnArgBase && ! fnArgBase->get_results().empty() );
    435                                         Type *argBaseType = fnArgBase->get_results().front();
    436                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
    437                                         arg++;
    438                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    439                                         arg++;
    440                                         if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    441                                                 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    442                                                         arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
    443                                                         arg++;
    444                                                 } else {
    445                                                         throw SemanticError( "Cannot pass non-struct type for generic struct" );
    446                                                 }
    447                                         }
    448 
    449                                         seenTypes.insert( sizeName );
    450                                 }
     461                                VariableExpr *fnArgBase = getBaseVar( *fnArg );
     462                                if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
     463                                passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
    451464                        }
    452465                }
     
    471484                        ObjectDecl *newObj = makeTemporary( retType->clone() );
    472485                        Expression *paramExpr = new VariableExpr( newObj );
    473                         // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
    474                         // temporary is already boxed and can be used directly.
     486
     487                        // If the type of the temporary is not polymorphic, box temporary by taking its address;
     488                        // otherwise the temporary is already boxed and can be used directly.
    475489                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
    476490                                paramExpr = new AddressExpr( paramExpr );
     
    521535                        assert( env );
    522536                        Type *concrete = replaceWithConcrete( appExpr, polyType );
     537                        // add out-parameter for return value   
    523538                        return addRetParam( appExpr, function, concrete, arg );
    524539                }
     
    543558                        assert( ! arg->get_results().empty() );
    544559                        if ( isPolyType( param, exprTyVars ) ) {
    545                                 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {
    546                                         // if the argument's type is a type parameter, we don't need to box again!
     560                                if ( isPolyType( arg->get_results().front() ) ) {
     561                                        // if the argument's type is polymorphic, we don't need to box again!
    547562                                        return;
    548563                                } else if ( arg->get_results().front()->get_isLvalue() ) {
     
    623638                        assert( arg );
    624639                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
    625                                 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
     640                                if ( ! isPolyType( arg->get_type() ) ) {
    626641                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    627642                                        deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     
    918933                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    919934
    920                         if ( ReferenceToType *polyType = isPolyRet( function ) ) {
    921                                 ret = addPolyRetParam( appExpr, function, polyType, arg );
     935                        TyVarMap exprTyVars;
     936                        makeTyVarMap( function, exprTyVars );
     937                        ReferenceToType *polyRetType = 0;
     938
     939                        if ( polyRetType = isPolyRet( function ) ) {
     940                                ret = addPolyRetParam( appExpr, function, polyRetType, arg );
    922941                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    923942                                // std::cerr << "needs adapter: ";
     
    931950                        arg = appExpr->get_args().begin();
    932951
    933                         TyVarMap exprTyVars;
    934                         makeTyVarMap( function, exprTyVars );
    935 
    936                         passTypeVars( appExpr, arg, exprTyVars );
     952                        passTypeVars( appExpr, polyRetType, arg, exprTyVars );
    937953                        addInferredParams( appExpr, function, arg, exprTyVars );
    938954
     
    9931009                }
    9941010
     1011                /// Wraps a function declaration in a new pointer-to-function variable expression
     1012                VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
     1013                        // line below cloned from FixFunction.cc
     1014                        ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1015                                                                  new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1016                        functionObj->set_mangleName( functionDecl->get_mangleName() );
     1017                        return new VariableExpr( functionObj );
     1018                }
     1019               
    9951020                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    9961021                        if ( retval && returnStmt->get_expr() ) {
     
    10081033
    10091034                                // find assignment operator for (polymorphic) return type
    1010                                 DeclarationWithType *assignDecl = 0;
     1035                                ApplicationExpr *assignExpr = 0;
    10111036                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1037                                        // find assignment operator for type variable
    10121038                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10131039                                        if ( assignIter == assignOps.end() ) {
    10141040                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10151041                                        } // if
    1016                                         assignDecl = assignIter->second;
     1042                                        assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    10171043                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1044                                        // find assignment operator for generic type
    10181045                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10191046                                        if ( assignIter == scopedAssignOps.end() ) {
    10201047                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10211048                                        }
     1049
     1050                                        // wrap it up in an application expression
    10221051                                        DeclarationWithType *functionDecl = assignIter->second;
    1023                                         // line below cloned from FixFunction.cc
    1024                                         assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1025                                                                      new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1026                                         assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1052                                        assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
     1053                                        assignExpr->set_env( env->clone() );
     1054
     1055                                        // find each of its needed secondary assignment operators
     1056                                        std::list< Expression* > &tyParams = refType->get_parameters();
     1057                                        std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
     1058                                        std::list< Expression* >::const_iterator tyIt = tyParams.begin();
     1059                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
     1060                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
     1061                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1062
     1063                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1064                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1065                                                DeclarationWithType *actualDecl = asserts.front();
     1066                                                ReferenceToType *actualType = isAssignment( actualDecl );
     1067                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
     1068                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
     1069                                                assert( formalTypeExpr && "type parameters must be type expressions" );
     1070                                                Type *formalType = formalTypeExpr->get_type();
     1071                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1072                                               
     1073                                                DeclarationWithType *assertAssign = 0;
     1074                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1075                                                        std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1076                                                        if ( assertAssignIt == assignOps.end() ) {
     1077                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     1078                                                        }
     1079                                                        assertAssign = assertAssignIt->second;
     1080                                                        //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
     1081                                                } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
     1082                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
     1083                                                        if ( assertAssignIt == scopedAssignOps.end() ) {
     1084                                                                throw SemanticError( "No assignment operation found for ", formalReferenceType );
     1085                                                        }
     1086                                                        assertAssign = assertAssignIt->second;
     1087                                                } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
     1088                                               
     1089
     1090                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1091                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1092                                        }
    10271093                                }
    1028                                 assert( assignDecl );
     1094                                assert( assignExpr );
    10291095
    10301096                                // replace return statement with appropriate assignment to out parameter
    1031                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10321097                                Expression *retParm = new NameExpr( retval->get_name() );
    10331098                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    11811246                        }
    11821247
    1183                         // add size/align for generic types to parameter list
     1248                        // add size/align for generic parameter types to parameter list
    11841249                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    11851250                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     
    12961361
    12971362                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1298                                         if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1363                                        if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty()
     1364                                             || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
    12991365                                        else continue;
    13001366                                } else return i;
     
    13421408                        if ( ! objectType ) return memberExpr;
    13431409
     1410                        Expression *newMemberExpr = 0;
    13441411                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    13451412                                // look up offset index
     
    13511418                                fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
    13521419                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
    1353 
    1354                                 delete memberExpr;
    1355                                 return fieldLoc;
    1356                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1420                                newMemberExpr = fieldLoc;
     1421                        } else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
    13571422                                // union members are all at offset zero, so build appropriately-dereferenced variable
    1358                                 Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
    1359                                 delete memberExpr;
    1360                                 return derefdVar;
     1423                                newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth );
    13611424                        } else return memberExpr;
     1425                        assert( newMemberExpr );
     1426
     1427                        // wrap pointer members in appropriate cast
     1428                        if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) {
     1429                                CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) );
     1430                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     1431                                derefExpr->get_args().push_back( ptrCastExpr );
     1432                                newMemberExpr = derefExpr;
     1433                        }
     1434
     1435                        delete memberExpr;
     1436                        return newMemberExpr;
    13621437                }
    13631438
     
    13801455                                delete offsetofExpr;
    13811456                                return offsetInd;
    1382                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
     1457                        } else if ( dynamic_cast< UnionInstType* >( ty ) ) {
    13831458                                // all union members are at offset zero
    13841459                                delete offsetofExpr;
Note: See TracChangeset for help on using the changeset viewer.