Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r05d47278 r1cced28  
    2222
    2323#include "Box.h"
    24 #include "InstantiateGeneric.h"
    2524#include "PolyMutator.h"
    2625#include "FindFunction.h"
    27 #include "ScopedMap.h"
    2826#include "ScrubTyVars.h"
    2927
     
    7169                        virtual void doEndScope();
    7270                  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
    7671                        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
    7872                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, 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 );
     73                        Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg );
    8674                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    8775                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
    8876                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    8977                        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
    9178                        void findAssignOps( const std::list< TypeDecl *> &forall );
    9279                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    9380                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
    94                         /// Replaces intrinsic operator functions with their arithmetic desugaring
    9581                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
    96                         /// Inserts a new temporary variable into the current scope with an auto-generated name
    9782                        ObjectDecl *makeTemporary( Type *type );
    9883
    9984                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    10085                        std::map< std::string, DeclarationWithType *> assignOps;
    101                         ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
    10286                        std::stack< AdapterMap > adapters;
    10387                        DeclarationWithType *retval;
     
    123107                };
    124108
    125                 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    126                 class MemberExprFixer : public PolyMutator {
     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 {
    127111                  public:
    128112                        template< typename DeclClass >
     
    135119                        virtual Type *mutate( PointerType *pointerType );
    136120                        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 );
    151121                  private:
    152122                };
     
    163133        }
    164134
    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 
    191135        void box( std::list< Declaration *>& translationUnit ) {
    192136                Pass1 pass1;
    193137                Pass2 pass2;
    194                 MemberExprFixer memberFixer;
    195138                Pass3 pass3;
    196                 mutateTranslationUnit/*All*/( translationUnit, pass1 );
    197                 mutateTranslationUnit/*All*/( translationUnit, pass2 );
    198                 instantiateGeneric( translationUnit );
    199                 mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    200                 mutateTranslationUnit/*All*/( translationUnit, pass3 );
     139                mutateAll( translationUnit, pass1 );
     140                mutateAll( translationUnit, pass2 );
     141                mutateAll( translationUnit, pass3 );
    201142        }
    202143
     
    244185                }
    245186
    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 ) {
     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 ) {
    248189                        if ( decl->get_name() == "?=?" ) {
    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;
     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
    256200                                                                        } // if
    257201                                                                } // if
     
    261205                                } // if
    262206                        } // if
    263                         return 0;
     207                        return false;
    264208                }
    265209
     
    270214                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    271215                                        std::string typeName;
    272                                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
    273                                                 assignOps[ typeInst->get_name() ] = *assert;
     216                                        if ( checkAssignment( *assert, typeName ) ) {
     217                                                assignOps[ typeName ] = *assert;
    274218                                        } // if
    275219                                } // for
     
    278222
    279223                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                        
    287224                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    288225                                doBeginScope();
     
    294231                                // process polymorphic return value
    295232                                retval = 0;
    296                                 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     233                                std::string typeName;
     234                                if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    297235                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    298236
     
    318256                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    319257                                } // for
    320                                
    321258                                AdapterMap & adapters = Pass1::adapters.top();
    322259                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    369306                }
    370307
    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                
    394308                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    395309                        // pass size/align for type variables
     
    411325
    412326                        // add size/align for generic types to parameter list
     327                        //assert( ! appExpr->get_function()->get_results().empty() );
    413328                        if ( appExpr->get_function()->get_results().empty() ) return;
    414329                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    430345                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
    431346                                        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                                         }
    440347
    441348                                        seenTypes.insert( sizeName );
     
    479386                }
    480387
    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 ) {
     388                Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
     389                        ResolvExpr::EqvClass eqvClass;
    513390                        assert( env );
    514                         Type *concrete = replaceWithConcrete( appExpr, polyType );
     391                        Type *concrete = env->lookup( typeName );
     392                        if ( concrete == 0 ) {
     393                                throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
     394                        } // if
    515395                        return addRetParam( appExpr, function, concrete, arg );
    516396                }
     
    612492                        assert( arg );
    613493                        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 {
    614497                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    615498                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    618501                                        return deref;
    619502                                } // if
     503//     }
    620504                        } // if
    621505                        return new VariableExpr( param );
     
    907791                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    908792
    909                         if ( ReferenceToType *polyType = isPolyRet( function ) ) {
    910                                 ret = addPolyRetParam( appExpr, function, polyType, arg );
     793                        std::string typeName;
     794                        if ( isPolyRet( function, typeName ) ) {
     795                                ret = addPolyRetParam( appExpr, function, typeName, arg );
    911796                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    912797                                // std::cerr << "needs adapter: ";
     
    995880                                        delete castExpr;
    996881                                } //while
    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 ) );
     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 ) );
    1021889                                Expression *retParm = new NameExpr( retval->get_name() );
    1022890                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    1059927                        // push a copy of the current map
    1060928                        adapters.push(adapters.top());
    1061                         scopedAssignOps.beginScope();
    1062929                }
    1063930
    1064931                void Pass1::doEndScope() {
    1065932                        adapters.pop();
    1066                         scopedAssignOps.endScope();
    1067933                }
    1068934
     
    1132998
    1133999                        // move polymorphic return type to parameter list
    1134                         if ( isPolyRet( funcType ) ) {
     1000                        std::string typeName;
     1001                        if ( isPolyRet( funcType, typeName ) ) {
    11351002                                DeclarationWithType *ret = funcType->get_returnVals().front();
    11361003                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    11431010                        std::list< DeclarationWithType *> inferredParams;
    11441011                        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 );
    11471012//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    11481013                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    11711036
    11721037                        // add size/align for generic types to parameter list
    1173                         std::set< std::string > seenTypes; // sizeofName for generic types we've seen
     1038                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
    11741039                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    11751040                                Type *parmType = (*fnParm)->get_type();
     
    11781043                                        if ( seenTypes.count( sizeName ) ) continue;
    11791044
    1180                                         ObjectDecl *sizeParm, *alignParm, *offsetParm;
     1045                                        ObjectDecl *sizeParm, *alignParm;
    11811046                                        sizeParm = newObj.clone();
    11821047                                        sizeParm->set_name( sizeName );
     
    11881053                                        last = funcType->get_parameters().insert( last, alignParm );
    11891054                                        ++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                                         }
    11971055
    11981056                                        seenTypes.insert( sizeName );
     
    12081066                        scopeTyVars = oldtyVars;
    12091067                        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;
    13351068                }
    13361069
     
    13931126                        return ret;
    13941127                }
     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                }
    13951146        } // anonymous namespace
    13961147} // namespace GenPoly
Note: See TracChangeset for help on using the changeset viewer.