Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rba3706f re16294d  
    163163                        void premutate( DeclStmt *declStmt );
    164164                        Expression *postmutate( MemberExpr *memberExpr );
     165                        void premutate( AddressExpr *addrExpr );
     166                        Expression *postmutate( AddressExpr *addrExpr );
    165167                        Expression *postmutate( SizeofExpr *sizeofExpr );
    166168                        Expression *postmutate( AlignofExpr *alignofExpr );
     
    182184                        /// change the type of generic aggregate members to char[]
    183185                        void mutateMembers( AggregateDecl * aggrDecl );
     186                        /// returns the calculated sizeof expression for ty, or nullptr for use C sizeof()
     187                        Expression* genSizeof( Type* ty );
    184188
    185189                        /// Enters a new scope for type-variables, adding the type variables from ty
     
    193197                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    194198                        UniqueName bufNamer;                           ///< Namer for VLA buffers
     199                        Expression * addrMember = nullptr;             ///< AddressExpr argument is MemberExpr?
    195200                };
    196201
     
    215220        inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
    216221                bool seenIntrinsic = false;
    217                 SemanticError errors;
     222                SemanticErrorException errors;
    218223                for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    219224                        try {
     
    228233                                        assert( *i );
    229234                                } // if
    230                         } catch( SemanticError &e ) {
    231                                 e.set_location( (*i)->location );
     235                        } catch( SemanticErrorException &e ) {
    232236                                errors.append( e );
    233237                        } // try
     
    302306        Expression *makeOp( const std::string &name, Expression *arg ) {
    303307                UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    304                 expr->get_args().push_back( arg );
     308                expr->args.push_back( arg );
    305309                return expr;
    306310        }
     
    309313        Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
    310314                UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    311                 expr->get_args().push_back( lhs );
    312                 expr->get_args().push_back( rhs );
     315                expr->args.push_back( lhs );
     316                expr->args.push_back( rhs );
    313317                return expr;
    314318        }
     
    316320        /// Returns the dereference of a local pointer variable
    317321        Expression *derefVar( ObjectDecl *var ) {
    318                 return makeOp( "*?", new VariableExpr( var ) );
     322                return UntypedExpr::createDeref( new VariableExpr( var ) );
    319323        }
    320324
     
    380384                unsigned long n_members = 0;
    381385                bool firstMember = true;
    382                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    383                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
     386                for ( Declaration* member : structDecl->get_members() ) {
     387                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
    384388                        assert( dwt );
    385389                        Type *memberType = dwt->get_type();
     
    576580                                                }
    577581                                        } else {
    578                                                 throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType );
     582                                                SemanticError( argBaseType, "Cannot pass non-struct type for generic struct: " );
    579583                                        }
    580584                                }
     
    598602                                        } else {
    599603                                                // xxx - should this be an assertion?
    600                                                 throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr );
     604                                                SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) );
    601605                                        } // if
    602606                                } // if
     
    831835                                if ( ! isPolyType( arg->get_type() ) ) {
    832836                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    833                                         deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    834                                         deref->set_result( arg->get_type()->clone() );
     837                                        deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     838                                        deref->result = arg->get_type()->clone();
     839                                        deref->result->set_lvalue( true );
    835840                                        return deref;
    836841                                } // if
     
    987992
    988993                Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) {
    989                         if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) {
    990                                 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    991                                         if ( varExpr->get_var()->get_name() == "?[?]" ) {
     994                        if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->function ) ) {
     995                                if ( varExpr->var->linkage == LinkageSpec::Intrinsic ) {
     996                                        if ( varExpr->var->name == "?[?]" ) {
    992997                                                assert( appExpr->result );
    993998                                                assert( appExpr->get_args().size() == 2 );
    994                                                 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
    995                                                 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env );
     999                                                Type *baseType1 = isPolyPtr( appExpr->args.front()->result, scopeTyVars, env );
     1000                                                Type *baseType2 = isPolyPtr( appExpr->args.back()->result, scopeTyVars, env );
    9961001                                                assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
    9971002                                                UntypedExpr *ret = 0;
     
    11741179                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    11751180                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    1176                                         if ( name->get_name() == "*?" ) {
     1181                                        if ( name->name == "*?" ) {
    11771182                                                Expression *ret = expr->args.front();
    11781183                                                expr->args.clear();
     
    11871192                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
    11881193                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
    1189                         assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );
     1194                        assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() );
    11901195
    11911196                        bool needs = false;
    1192                         if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    1193                                 if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    1194                                         if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    1195                                                 if ( name->get_name() == "*?" ) {
    1196                                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    1197                                                                 assert( appExpr->get_function()->result );
    1198                                                                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
     1197                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
     1198                                if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
     1199                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     1200                                                if ( name->name == "*?" ) {
     1201                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
     1202                                                                assert( appExpr->function->result );
     1203                                                                FunctionType *function = getFunctionType( appExpr->function->result );
    11991204                                                                assert( function );
    12001205                                                                needs = needsAdapter( function, scopeTyVars );
     
    12061211                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    12071212                        // out of the if condition.
    1208                         addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
     1213                        addrExpr->arg = addrExpr->arg->acceptMutator( *visitor );
    12091214                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    1210                         bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     1215                        bool polytype = isPolyType( addrExpr->arg->result, scopeTyVars, env );
    12111216                        if ( polytype || needs ) {
    1212                                 Expression *ret = addrExpr->get_arg();
    1213                                 delete ret->get_result();
    1214                                 ret->set_result( addrExpr->get_result()->clone() );
    1215                                 addrExpr->set_arg( 0 );
     1217                                Expression *ret = addrExpr->arg;
     1218                                delete ret->result;
     1219                                ret->result = addrExpr->result->clone();
     1220                                addrExpr->arg = nullptr;
    12161221                                delete addrExpr;
    12171222                                return ret;
     
    12501255
    12511256                void Pass2::addAdapters( FunctionType *functionType ) {
    1252                         std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     1257                        std::list< DeclarationWithType *> &paramList = functionType->parameters;
    12531258                        std::list< FunctionType *> functions;
    12541259                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     
    12711276
    12721277                DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
    1273                         FunctionType * ftype = functionDecl->get_functionType();
    1274                         if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
    1275                                 if ( ! isPrefix( functionDecl->get_name(), "_thunk" ) && ! isPrefix( functionDecl->get_name(), "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
    1276                                         assert( ftype->get_returnVals().size() == 1 );
    1277                                         DeclarationWithType * retval = ftype->get_returnVals().front();
    1278                                         if ( retval->get_name() == "" ) {
    1279                                                 retval->set_name( "_retval" );
     1278                        FunctionType * ftype = functionDecl->type;
     1279                        if ( ! ftype->returnVals.empty() && functionDecl->statements ) {
     1280                                if ( ! isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
     1281                                        assert( ftype->returnVals.size() == 1 );
     1282                                        DeclarationWithType * retval = ftype->returnVals.front();
     1283                                        if ( retval->name == "" ) {
     1284                                                retval->name = "_retval";
    12801285                                        }
    1281                                         functionDecl->get_statements()->get_kids().push_front( new DeclStmt( retval ) );
     1286                                        functionDecl->statements->kids.push_front( new DeclStmt( retval ) );
    12821287                                        DeclarationWithType * newRet = retval->clone(); // for ownership purposes
    1283                                         ftype->get_returnVals().front() = newRet;
     1288                                        ftype->returnVals.front() = newRet;
    12841289                                }
    12851290                        }
    12861291                        // errors should have been caught by this point, remove initializers from parameters to allow correct codegen of default arguments
    1287                         for ( Declaration * param : functionDecl->get_functionType()->get_parameters() ) {
     1292                        for ( Declaration * param : functionDecl->type->parameters ) {
    12881293                                if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) {
    1289                                         delete obj->get_init();
    1290                                         obj->set_init( nullptr );
     1294                                        delete obj->init;
     1295                                        obj->init = nullptr;
    12911296                                }
    12921297                        }
     
    15541559                        // only mutate member expressions for polymorphic types
    15551560                        int tyDepth;
    1556                         Type *objectType = hasPolyBase( memberExpr->get_aggregate()->get_result(), scopeTyVars, &tyDepth );
     1561                        Type *objectType = hasPolyBase( memberExpr->aggregate->result, scopeTyVars, &tyDepth );
    15571562                        if ( ! objectType ) return memberExpr;
    15581563                        findGeneric( objectType ); // ensure layout for this type is available
    15591564
    15601565                        // replace member expression with dynamically-computed layout expression
    1561                         Expression *newMemberExpr = 0;
     1566                        Expression *newMemberExpr = nullptr;
    15621567                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    15631568                                // look up offset index
    1564                                 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
     1569                                long i = findMember( memberExpr->member, structType->baseStruct->members );
    15651570                                if ( i == -1 ) return memberExpr;
    15661571
    15671572                                // replace member expression with pointer to base plus offset
    15681573                                UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1569                                 Expression * aggr = memberExpr->get_aggregate()->clone();
    1570                                 delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
    1571                                 aggr->set_env( nullptr );
     1574                                Expression * aggr = memberExpr->aggregate->clone();
     1575                                delete aggr->env; // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
     1576                                aggr->env = nullptr;
    15721577                                fieldLoc->get_args().push_back( aggr );
    15731578                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
    1574                                 fieldLoc->set_result( memberExpr->get_result()->clone() );
     1579                                fieldLoc->set_result( memberExpr->result->clone() );
    15751580                                newMemberExpr = fieldLoc;
    15761581                        } else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
    15771582                                // union members are all at offset zero, so just use the aggregate expr
    1578                                 Expression * aggr = memberExpr->get_aggregate()->clone();
    1579                                 delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
    1580                                 aggr->set_env( nullptr );
     1583                                Expression * aggr = memberExpr->aggregate->clone();
     1584                                delete aggr->env; // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
     1585                                aggr->env= nullptr;
    15811586                                newMemberExpr = aggr;
    1582                                 newMemberExpr->set_result( memberExpr->get_result()->clone() );
     1587                                newMemberExpr->result = memberExpr->result->clone();
    15831588                        } else return memberExpr;
    15841589                        assert( newMemberExpr );
    15851590
    1586                         Type *memberType = memberExpr->get_member()->get_type();
     1591                        // Must apply the generic substitution to the member type to handle cases where the member is a generic parameter substituted by a known concrete type, e.g.
     1592                        //   forall(otype T) struct Box { T x; }
     1593                        //   forall(otype T) f() {
     1594                        //     Box(T *) b; b.x;
     1595                        //   }
     1596                        // TODO: memberExpr->result should be exactly memberExpr->member->get_type() after substitution, so it doesn't seem like it should be necessary to apply the substitution manually. For some reason this is not currently the case. This requires more investigation.
     1597                        Type *memberType = memberExpr->member->get_type()->clone();
     1598                        TypeSubstitution sub = objectType->genericSubstitution();
     1599                        sub.apply( memberType );
    15871600                        if ( ! isPolyType( memberType, scopeTyVars ) ) {
    15881601                                // Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue
     
    15921605                        }
    15931606
     1607                        delete memberType;
    15941608                        delete memberExpr;
    15951609                        return newMemberExpr;
    15961610                }
    15971611
     1612                void PolyGenericCalculator::premutate( AddressExpr * addrExpr ) {
     1613                        GuardValue( addrMember );
     1614                        // is the argument a MemberExpr before mutating?
     1615                        addrMember = dynamic_cast< MemberExpr * >( addrExpr->arg );
     1616                }
     1617
     1618                Expression * PolyGenericCalculator::postmutate( AddressExpr * addrExpr ) {
     1619                        if ( addrMember && addrMember != addrExpr->arg ) {
     1620                                // arg was a MemberExpr and has been mutated
     1621                                if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( addrExpr->arg ) ) {
     1622                                        if ( InitTweak::getFunctionName( untyped ) == "?+?" ) {
     1623                                                // MemberExpr was converted to pointer+offset, and it is not valid C to take the address of an addition, so strip the address-of
     1624                                                // TODO: should  addrExpr->arg->result be changed to addrExpr->result?
     1625                                                Expression * ret = addrExpr->arg;
     1626                                                addrExpr->arg = nullptr;
     1627                                                std::swap( addrExpr->env, ret->env );
     1628                                                delete addrExpr;
     1629                                                return ret;
     1630                                        }
     1631                                }
     1632                        }
     1633                        return addrExpr;
     1634                }
     1635
    15981636                ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
    1599                         ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init );
     1637                        ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, nullptr, type, init );
    16001638                        stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
    16011639                        return newObj;
     
    17111749                }
    17121750
     1751                Expression * PolyGenericCalculator::genSizeof( Type* ty ) {
     1752                        if ( ArrayType * aty = dynamic_cast<ArrayType *>(ty) ) {
     1753                                // generate calculated size for possibly generic array
     1754                                Expression * sizeofBase = genSizeof( aty->get_base() );
     1755                                if ( ! sizeofBase ) return nullptr;
     1756                                Expression * dim = aty->get_dimension();
     1757                                aty->set_dimension( nullptr );
     1758                                return makeOp( "?*?", sizeofBase, dim );
     1759                        } else if ( findGeneric( ty ) ) {
     1760                                // generate calculated size for generic type
     1761                                return new NameExpr( sizeofName( mangleType( ty ) ) );
     1762                        } else return nullptr;
     1763                }
     1764
    17131765                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    1714                         Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    1715                         if ( findGeneric( ty ) ) {
    1716                                 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
     1766                        Type *ty = sizeofExpr->get_isType() ?
     1767                                sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
     1768                       
     1769                        Expression * gen = genSizeof( ty );
     1770                        if ( gen ) {
    17171771                                delete sizeofExpr;
    1718                                 return ret;
    1719                         }
    1720                         return sizeofExpr;
     1772                                return gen;
     1773                        } else return sizeofExpr;
    17211774                }
    17221775
Note: See TracChangeset for help on using the changeset viewer.