Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r1cced28 r05d47278  
    2222
    2323#include "Box.h"
     24#include "InstantiateGeneric.h"
    2425#include "PolyMutator.h"
    2526#include "FindFunction.h"
     27#include "ScopedMap.h"
    2628#include "ScrubTyVars.h"
    2729
     
    6971                        virtual void doEndScope();
    7072                  private:
     73                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
     74                        Expression *makeOffsetArray( StructInstType *type );
     75                        /// passes extra type parameters into a polymorphic function application
    7176                        void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     77                        /// wraps a function application with a new temporary for the out-parameter return value
    7278                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
    73                         Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg );
     79                        /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
     80                        void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params );
     81                        /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
     82                        /// If `doClone` is set to false, will not clone interior types
     83                        Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
     84                        /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
     85                        Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
    7486                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7587                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
    7688                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7789                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
     90                        /// Stores assignment operators from assertion list in local map of assignment operations
    7891                        void findAssignOps( const std::list< TypeDecl *> &forall );
    7992                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    8093                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     94                        /// Replaces intrinsic operator functions with their arithmetic desugaring
    8195                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
     96                        /// Inserts a new temporary variable into the current scope with an auto-generated name
    8297                        ObjectDecl *makeTemporary( Type *type );
    8398
    8499                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    85100                        std::map< std::string, DeclarationWithType *> assignOps;
     101                        ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
    86102                        std::stack< AdapterMap > adapters;
    87103                        DeclarationWithType *retval;
     
    107123                };
    108124
    109                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    110                 class Pass3 : public PolyMutator {
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
     126                class MemberExprFixer : public PolyMutator {
    111127                  public:
    112128                        template< typename DeclClass >
     
    119135                        virtual Type *mutate( PointerType *pointerType );
    120136                        virtual Type *mutate( FunctionType *funcType );
     137                        virtual Expression *mutate( MemberExpr *memberExpr );
     138                };
     139               
     140                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
     141                class Pass3 : public PolyMutator {
     142                  public:
     143                        template< typename DeclClass >
     144                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     145                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
     146                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
     147                        virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
     148                        virtual TypeDecl *mutate( TypeDecl *objectDecl );
     149                        virtual Type *mutate( PointerType *pointerType );
     150                        virtual Type *mutate( FunctionType *funcType );
    121151                  private:
    122152                };
     
    133163        }
    134164
     165        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
     166        template< typename MutatorType >
     167        inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
     168                bool seenIntrinsic = false;
     169                SemanticError errors;
     170                for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     171                        try {
     172                                if ( *i ) {
     173                                        if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
     174                                                seenIntrinsic = true;
     175                                        } else if ( seenIntrinsic ) {
     176                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
     177                                        }
     178                                       
     179                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
     180                                        assert( *i );
     181                                } // if
     182                        } catch( SemanticError &e ) {
     183                                errors.append( e );
     184                        } // try
     185                } // for
     186                if ( ! errors.isEmpty() ) {
     187                        throw errors;
     188                } // if
     189        }
     190
    135191        void box( std::list< Declaration *>& translationUnit ) {
    136192                Pass1 pass1;
    137193                Pass2 pass2;
     194                MemberExprFixer memberFixer;
    138195                Pass3 pass3;
    139                 mutateAll( translationUnit, pass1 );
    140                 mutateAll( translationUnit, pass2 );
    141                 mutateAll( translationUnit, pass3 );
     196                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     197                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     198                instantiateGeneric( translationUnit );
     199                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     200                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    142201        }
    143202
     
    185244                }
    186245
    187                 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)
    188                 bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
     246                /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise
     247                ReferenceToType *isAssignment( DeclarationWithType *decl ) {
    189248                        if ( decl->get_name() == "?=?" ) {
    190                                 if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) {
    191                                         if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) {
    192                                                 if ( funType->get_parameters().size() == 2 ) {
    193                                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    194                                                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    195                                                                         if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    196                                                                                 if ( typeInst->get_name() == typeInst2->get_name() ) {
    197                                                                                         name = typeInst->get_name();
    198                                                                                         return true;
    199                                                                                 } // if
     249                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     250                                        if ( funType->get_parameters().size() == 2 ) {
     251                                                if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     252                                                        if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {
     253                                                                if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {
     254                                                                        if ( refType->get_name() == refType2->get_name() ) {
     255                                                                                return refType;
    200256                                                                        } // if
    201257                                                                } // if
     
    205261                                } // if
    206262                        } // if
    207                         return false;
     263                        return 0;
    208264                }
    209265
     
    214270                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    215271                                        std::string typeName;
    216                                         if ( checkAssignment( *assert, typeName ) ) {
    217                                                 assignOps[ typeName ] = *assert;
     272                                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
     273                                                assignOps[ typeInst->get_name() ] = *assert;
    218274                                        } // if
    219275                                } // for
     
    222278
    223279                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     280                        // if this is a polymorphic assignment function, put it in the map for this scope
     281                        if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {
     282                                if ( ! dynamic_cast< TypeInstType* >( refType ) ) {
     283                                        scopedAssignOps.insert( refType->get_name(), functionDecl );
     284                                }
     285                        }
     286                       
    224287                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    225288                                doBeginScope();
     
    231294                                // process polymorphic return value
    232295                                retval = 0;
    233                                 std::string typeName;
    234                                 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     296                                if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    235297                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    236298
     
    256318                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    257319                                } // for
     320                               
    258321                                AdapterMap & adapters = Pass1::adapters.top();
    259322                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    306369                }
    307370
     371                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     372                        // make a new temporary array
     373                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     374                        ObjectDecl *arrayTemp = makeTemporary( new PointerType( Type::Qualifiers(), offsetType ) );
     375
     376                        // build initializer list for temporary
     377                        std::list< Initializer* > inits;
     378                        StructDecl *tyBase = ty->get_baseStruct();
     379                        for ( std::list< Declaration* >::const_iterator member = tyBase->get_members().begin(); member != tyBase->get_members().end(); ++member ) {
     380                                DeclarationWithType *memberDecl;
     381                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     382                                        memberDecl = origMember->clone();
     383                                } else {
     384                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     385                                }
     386                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     387                        }
     388                        arrayTemp->set_init( new ListInit( inits ) );
     389
     390                        // return variable pointing to temporary
     391                        return new VariableExpr( arrayTemp );
     392                }
     393               
    308394                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    309395                        // pass size/align for type variables
     
    325411
    326412                        // add size/align for generic types to parameter list
    327                         //assert( ! appExpr->get_function()->get_results().empty() );
    328413                        if ( appExpr->get_function()->get_results().empty() ) return;
    329414                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    345430                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
    346431                                        arg++;
     432                                        if ( dynamic_cast< StructInstType* >( parmType ) ) {
     433                                                if ( StructInstType *argStructType = dynamic_cast< StructInstType* >( argType ) ) {
     434                                                        arg = appExpr->get_args().insert( arg, makeOffsetArray( argStructType ) );
     435                                                        arg++;
     436                                                } else {
     437                                                        throw SemanticError( "Cannot pass non-struct type for generic struct" );
     438                                                }
     439                                        }
    347440
    348441                                        seenTypes.insert( sizeName );
     
    386479                }
    387480
    388                 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
    389                         ResolvExpr::EqvClass eqvClass;
     481                void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
     482                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     483                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     484                                assert(paramType && "Aggregate parameters should be type expressions");
     485                                paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
     486                        }
     487                }
     488               
     489                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
     490                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     491                                Type *concrete = env->lookup( typeInst->get_name() );
     492                                if ( concrete == 0 ) {
     493                                        throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
     494                                } // if
     495                                return concrete;
     496                        } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     497                                if ( doClone ) {
     498                                        structType = structType->clone();
     499                                }
     500                                replaceParametersWithConcrete( appExpr, structType->get_parameters() );
     501                                return structType;
     502                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     503                                if ( doClone ) {
     504                                        unionType = unionType->clone();
     505                                }
     506                                replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
     507                                return unionType;
     508                        }
     509                        return type;
     510                }
     511
     512                Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
    390513                        assert( env );
    391                         Type *concrete = env->lookup( typeName );
    392                         if ( concrete == 0 ) {
    393                                 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
    394                         } // if
     514                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    395515                        return addRetParam( appExpr, function, concrete, arg );
    396516                }
     
    492612                        assert( arg );
    493613                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
    494 //     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    495 //       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    496 //     } else {
    497614                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    498615                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    501618                                        return deref;
    502619                                } // if
    503 //     }
    504620                        } // if
    505621                        return new VariableExpr( param );
     
    791907                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    792908
    793                         std::string typeName;
    794                         if ( isPolyRet( function, typeName ) ) {
    795                                 ret = addPolyRetParam( appExpr, function, typeName, arg );
     909                        if ( ReferenceToType *polyType = isPolyRet( function ) ) {
     910                                ret = addPolyRetParam( appExpr, function, polyType, arg );
    796911                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    797912                                // std::cerr << "needs adapter: ";
     
    880995                                        delete castExpr;
    881996                                } //while
    882                                 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    883                                 assert( typeInst );
    884                                 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    885                                 if ( assignIter == assignOps.end() ) {
    886                                         throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    887                                 } // if
    888                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     997
     998                                // find assignment operator for (polymorphic) return type
     999                                DeclarationWithType *assignDecl = 0;
     1000                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1001                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     1002                                        if ( assignIter == assignOps.end() ) {
     1003                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     1004                                        } // if
     1005                                        assignDecl = assignIter->second;
     1006                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1007                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
     1008                                        if ( assignIter == scopedAssignOps.end() ) {
     1009                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
     1010                                        }
     1011                                        DeclarationWithType *functionDecl = assignIter->second;
     1012                                        // line below cloned from FixFunction.cc
     1013                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1014                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1015                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1016                                }
     1017                                assert( assignDecl );
     1018
     1019                                // replace return statement with appropriate assignment to out parameter
     1020                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    8891021                                Expression *retParm = new NameExpr( retval->get_name() );
    8901022                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    9271059                        // push a copy of the current map
    9281060                        adapters.push(adapters.top());
     1061                        scopedAssignOps.beginScope();
    9291062                }
    9301063
    9311064                void Pass1::doEndScope() {
    9321065                        adapters.pop();
     1066                        scopedAssignOps.endScope();
    9331067                }
    9341068
     
    9981132
    9991133                        // move polymorphic return type to parameter list
    1000                         std::string typeName;
    1001                         if ( isPolyRet( funcType, typeName ) ) {
     1134                        if ( isPolyRet( funcType ) ) {
    10021135                                DeclarationWithType *ret = funcType->get_returnVals().front();
    10031136                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    10101143                        std::list< DeclarationWithType *> inferredParams;
    10111144                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1145                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
     1146                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    10121147//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10131148                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    10361171
    10371172                        // add size/align for generic types to parameter list
    1038                         std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1173                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    10391174                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    10401175                                Type *parmType = (*fnParm)->get_type();
     
    10431178                                        if ( seenTypes.count( sizeName ) ) continue;
    10441179
    1045                                         ObjectDecl *sizeParm, *alignParm;
     1180                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    10461181                                        sizeParm = newObj.clone();
    10471182                                        sizeParm->set_name( sizeName );
     
    10531188                                        last = funcType->get_parameters().insert( last, alignParm );
    10541189                                        ++last;
     1190
     1191                                        if ( dynamic_cast< StructInstType* >( parmType ) ) {
     1192                                                offsetParm = newPtr.clone();
     1193                                                offsetParm->set_name( offsetofName( parmType ) );
     1194                                                last = funcType->get_parameters().insert( last, offsetParm );
     1195                                                ++last;
     1196                                        }
    10551197
    10561198                                        seenTypes.insert( sizeName );
     
    10661208                        scopeTyVars = oldtyVars;
    10671209                        return funcType;
     1210                }
     1211
     1212////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
     1213
     1214                template< typename DeclClass >
     1215                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1216                        TyVarMap oldtyVars = scopeTyVars;
     1217                        makeTyVarMap( type, scopeTyVars );
     1218
     1219                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1220
     1221                        scopeTyVars = oldtyVars;
     1222                        return ret;
     1223                }
     1224
     1225                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
     1226                        return handleDecl( objectDecl, objectDecl->get_type() );
     1227                }
     1228
     1229                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
     1230                        return handleDecl( functionDecl, functionDecl->get_functionType() );
     1231                }
     1232
     1233                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
     1234                        return handleDecl( typedefDecl, typedefDecl->get_base() );
     1235                }
     1236
     1237                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
     1238                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1239                        return Mutator::mutate( typeDecl );
     1240                }
     1241
     1242                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1243                        TyVarMap oldtyVars = scopeTyVars;
     1244                        makeTyVarMap( pointerType, scopeTyVars );
     1245
     1246                        Type *ret = Mutator::mutate( pointerType );
     1247
     1248                        scopeTyVars = oldtyVars;
     1249                        return ret;
     1250                }
     1251
     1252                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1253                        TyVarMap oldtyVars = scopeTyVars;
     1254                        makeTyVarMap( functionType, scopeTyVars );
     1255
     1256                        Type *ret = Mutator::mutate( functionType );
     1257
     1258                        scopeTyVars = oldtyVars;
     1259                        return ret;
     1260                }
     1261
     1262                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
     1263                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1264                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1265                                        // change initialization of a polymorphic value object
     1266                                        // to allocate storage with alloca
     1267                                        Type *declType = objectDecl->get_type();
     1268                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
     1269                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1270
     1271                                        delete objectDecl->get_init();
     1272
     1273                                        std::list<Expression*> designators;
     1274                                        objectDecl->set_init( new SingleInit( alloc, designators ) );
     1275                                }
     1276                        }
     1277                        return Mutator::mutate( declStmt );
     1278                }
     1279
     1280                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1281                        // mutate, exiting early if no longer MemberExpr
     1282                        Expression *expr = Mutator::mutate( memberExpr );
     1283                        memberExpr = dynamic_cast< MemberExpr* >( expr );
     1284                        if ( ! memberExpr ) return expr;
     1285
     1286                        // get declaration for base struct, exiting early if not found
     1287                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() );
     1288                        if ( ! varExpr ) return memberExpr;
     1289                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1290                        if ( ! objectDecl ) return memberExpr;
     1291
     1292                        // only mutate member expressions for polymorphic types
     1293                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars );
     1294                        if ( ! objectType ) return memberExpr;
     1295
     1296                        // get base aggregate for type so members can be looked up
     1297                        AggregateDecl *memberBase = 0;
     1298                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     1299                                memberBase = structType->get_baseStruct();
     1300                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1301                                memberBase = unionType->get_baseUnion();
     1302                        } else return memberExpr;
     1303
     1304                        // look up numeric index of member in base aggregate
     1305                        DeclarationWithType *memberDecl = memberExpr->get_member();
     1306                        std::list< Declaration* > &baseDecls = memberBase->get_members();
     1307                        std::list< Declaration* >::const_iterator decl = baseDecls.begin();
     1308                        unsigned long i = 0;
     1309                        for( ; decl != baseDecls.end(); ++decl, ++i ) {
     1310                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1311
     1312                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1313                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
     1314                                        else continue;
     1315                                } else break;
     1316                        }
     1317                        if ( decl == baseDecls.end() ) return memberExpr;
     1318
     1319                        // replace member expression with dereference of pointer offset
     1320                        std::stringstream offset_namer;
     1321                        offset_namer << i;
     1322                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1323                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1324                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1325                        fieldOffset->get_args().push_back( fieldIndex );
     1326                        UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1327                        fieldLoc->get_args().push_back( memberExpr->get_aggregate() );
     1328                        fieldLoc->get_args().push_back( fieldOffset );
     1329                        UntypedExpr *ret = new UntypedExpr( new NameExpr( "*?" ) );
     1330                        ret->get_args().push_back( fieldLoc );
     1331
     1332                        memberExpr->set_aggregate( 0 );
     1333                        delete memberExpr;
     1334                        return ret;
    10681335                }
    10691336
     
    11261393                        return ret;
    11271394                }
    1128 
    1129                 Statement *Pass3::mutate( DeclStmt *declStmt ) {
    1130                         if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1131                                 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    1132                                         // change initialization of a polymorphic value object
    1133                                         // to allocate storage with alloca
    1134                                         Type *declType = objectDecl->get_type();
    1135                                         UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1136                                         alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    1137 
    1138                                         delete objectDecl->get_init();
    1139 
    1140                                         std::list<Expression*> designators;
    1141                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
    1142                                 }
    1143                         }
    1144                         return Mutator::mutate( declStmt );
    1145                 }
    11461395        } // anonymous namespace
    11471396} // namespace GenPoly
Note: See TracChangeset for help on using the changeset viewer.