Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rb10c9959 rb4cd03b7  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Dec 18 14:53:08 2015
    13 // Update Count     : 217
     12// Last Modified On : Fri Feb 05 12:23:10 2016
     13// Update Count     : 280
    1414//
    1515
     
    123123                };
    124124
    125                 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
    126                 /// also fixes offsetof expressions.
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    127126                class MemberExprFixer : public PolyMutator {
    128127                  public:
     
    137136                        virtual Type *mutate( FunctionType *funcType );
    138137                        virtual Expression *mutate( MemberExpr *memberExpr );
    139                         virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    140138                };
    141                
     139
    142140                /// 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
    143141                class Pass3 : public PolyMutator {
     
    178176                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
    179177                                        }
    180                                        
     178
    181179                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
    182180                                        assert( *i );
     
    286284                                }
    287285                        }
    288                        
     286
    289287                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    290288                                doBeginScope();
     
    320318                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    321319                                } // for
    322                                
     320
    323321                                AdapterMap & adapters = Pass1::adapters.top();
    324322                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    373371                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
    374372                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    375                        
     373
    376374                        // make a new temporary array
    377375                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     
    397395                        return new VariableExpr( arrayTemp );
    398396                }
    399                
     397
    400398                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    401399                        // pass size/align for type variables
     
    493491                        }
    494492                }
    495                
     493
    496494                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
    497495                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     
    531529                        std::string adapterName = makeAdapterName( mangleName );
    532530
    533                         appExpr->get_args().push_front( appExpr->get_function() );
     531                        // cast adaptee to void (*)(), since it may have any type inside a polymorphic function
     532                        Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
     533                        appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
    534534                        appExpr->set_function( new NameExpr( adapterName ) );
    535535
     
    559559                }
    560560
     561                /// cast parameters to polymorphic functions so that types are replaced with
     562                /// void * if they are type parameters in the formal type.
     563                /// this gets rid of warnings from gcc.
    561564                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    562                         Type *newType = formal->clone();
    563                         std::list< FunctionType *> functions;
    564                         // instead of functions needing adapters, this really ought to look for
    565                         // any function mentioning a polymorphic type
    566                         findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    567                         if ( ! functions.empty() ) {
     565                        Type * newType = formal->clone();
     566                        if ( getFunctionType( newType ) ) {
     567                                newType = ScrubTyVars::scrub( newType, tyVars );
    568568                                actual = new CastExpr( actual, newType );
    569                         } else {
    570                                 delete newType;
    571569                        } // if
    572570                }
     
    989987                }
    990988
    991                 /// Wraps a function declaration in a new pointer-to-function variable expression
    992                 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
    993                         // line below cloned from FixFunction.cc
    994                         ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    995                                                                   new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    996                         functionObj->set_mangleName( functionDecl->get_mangleName() );
    997                         return new VariableExpr( functionObj );
    998                 }
    999                
    1000989                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    1001990                        if ( retval && returnStmt->get_expr() ) {
     
    10131002
    10141003                                // find assignment operator for (polymorphic) return type
    1015                                 ApplicationExpr *assignExpr = 0;
     1004                                DeclarationWithType *assignDecl = 0;
    10161005                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    1017                                         // find assignment operator for type variable
    10181006                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10191007                                        if ( assignIter == assignOps.end() ) {
    10201008                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10211009                                        } // if
    1022                                         assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     1010                                        assignDecl = assignIter->second;
    10231011                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    1024                                         // find assignment operator for generic type
    10251012                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10261013                                        if ( assignIter == scopedAssignOps.end() ) {
    10271014                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10281015                                        }
    1029 
    1030                                         // wrap it up in an application expression
    10311016                                        DeclarationWithType *functionDecl = assignIter->second;
    1032                                         assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
    1033                                         assignExpr->set_env( env->clone() );
    1034 
    1035                                         // find each of its needed secondary assignment operators
    1036                                         std::list< Expression* > &tyParams = refType->get_parameters();
    1037                                         std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
    1038                                         std::list< Expression* >::const_iterator tyIt = tyParams.begin();
    1039                                         std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    1040                                         for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1041                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
    1042 
    1043                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1044                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1045                                                 DeclarationWithType *actualDecl = asserts.front();
    1046                                                 ReferenceToType *actualType = isAssignment( actualDecl );
    1047                                                 assert( actualType && "First assertion of type with assertions should be assignment operator" );
    1048                                                 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    1049                                                 assert( formalTypeExpr && "type parameters must be type expressions" );
    1050                                                 Type *formalType = formalTypeExpr->get_type();
    1051                                                 assignExpr->get_env()->add( actualType->get_name(), formalType );
    1052                                                
    1053                                                 DeclarationWithType *assertAssign = 0;
    1054                                                 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1055                                                         std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
    1056                                                         if ( assertAssignIt == assignOps.end() ) {
    1057                                                                 throw SemanticError( "No assignment operation found for ", formalTypeInstType );
    1058                                                         }
    1059                                                         assertAssign = assertAssignIt->second;
    1060                                                         //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
    1061                                                 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
    1062                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
    1063                                                         if ( assertAssignIt == scopedAssignOps.end() ) {
    1064                                                                 throw SemanticError( "No assignment operation found for ", formalReferenceType );
    1065                                                         }
    1066                                                         assertAssign = assertAssignIt->second;
    1067                                                 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
    1068                                                
    1069 
    1070                                                 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1071                                                         = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
    1072                                         }
     1017                                        // line below cloned from FixFunction.cc
     1018                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1019                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1020                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
    10731021                                }
    1074                                 assert( assignExpr );
     1022                                assert( assignDecl );
    10751023
    10761024                                // replace return statement with appropriate assignment to out parameter
     1025                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10771026                                Expression *retParm = new NameExpr( retval->get_name() );
    10781027                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    13341283                }
    13351284
    1336                 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
    1337                 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
    1338                         long i = 0;
    1339                         for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
     1285                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1286                        // mutate, exiting early if no longer MemberExpr
     1287                        Expression *expr = Mutator::mutate( memberExpr );
     1288                        memberExpr = dynamic_cast< MemberExpr* >( expr );
     1289                        if ( ! memberExpr ) return expr;
     1290
     1291                        // get declaration for base struct, exiting early if not found
     1292                        int varDepth;
     1293                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
     1294                        if ( ! varExpr ) return memberExpr;
     1295                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1296                        if ( ! objectDecl ) return memberExpr;
     1297
     1298                        // only mutate member expressions for polymorphic types
     1299                        int tyDepth;
     1300                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
     1301                        if ( ! objectType ) return memberExpr;
     1302
     1303                        // get base aggregate for type so members can be looked up
     1304                        AggregateDecl *memberBase = 0;
     1305                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     1306                                memberBase = structType->get_baseStruct();
     1307                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1308                                memberBase = unionType->get_baseUnion();
     1309                        } else return memberExpr;
     1310
     1311                        // look up numeric index of member in base aggregate
     1312                        DeclarationWithType *memberDecl = memberExpr->get_member();
     1313                        std::list< Declaration* > &baseDecls = memberBase->get_members();
     1314                        std::list< Declaration* >::const_iterator decl = baseDecls.begin();
     1315                        unsigned long i = 0;
     1316                        for( ; decl != baseDecls.end(); ++decl, ++i ) {
    13401317                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
    13411318
    13421319                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1343                                         if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1320                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
    13441321                                        else continue;
    1345                                 } else return i;
     1322                                } else break;
    13461323                        }
    1347                         return -1;
    1348                 }
    1349 
    1350                 /// Returns an index expression into the offset array for a type
    1351                 Expression *makeOffsetIndex( Type *objectType, long i ) {
     1324                        if ( decl == baseDecls.end() ) return memberExpr;
     1325
     1326                        // replace member expression with pointer to base plus offset
     1327                        // get offset for field
    13521328                        std::stringstream offset_namer;
    13531329                        offset_namer << i;
     
    13561332                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    13571333                        fieldOffset->get_args().push_back( fieldIndex );
    1358                         return fieldOffset;
    1359                 }
    1360 
    1361                 /// Returns an expression dereferenced n times
    1362                 Expression *makeDerefdVar( Expression *derefdVar, long n ) {
    1363                         for ( int i = 1; i < n; ++i ) {
     1334                        // build appropriately-dereferenced variable
     1335                        Expression *derefdVar = varExpr->clone();
     1336                        for ( int i = 1; i < varDepth; ++i ) {
    13641337                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    13651338                                derefExpr->get_args().push_back( derefdVar );
    13661339                                derefdVar = derefExpr;
    13671340                        }
    1368                         return derefdVar;
    1369                 }
    1370                
    1371                 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    1372                         // mutate, exiting early if no longer MemberExpr
    1373                         Expression *expr = Mutator::mutate( memberExpr );
    1374                         memberExpr = dynamic_cast< MemberExpr* >( expr );
    1375                         if ( ! memberExpr ) return expr;
    1376 
    1377                         // get declaration for base struct, exiting early if not found
    1378                         int varDepth;
    1379                         VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
    1380                         if ( ! varExpr ) return memberExpr;
    1381                         ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1382                         if ( ! objectDecl ) return memberExpr;
    1383 
    1384                         // only mutate member expressions for polymorphic types
    1385                         int tyDepth;
    1386                         Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
    1387                         if ( ! objectType ) return memberExpr;
    1388 
    1389                         if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    1390                                 // look up offset index
    1391                                 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
    1392                                 if ( i == -1 ) return memberExpr;
    1393 
    1394                                 // replace member expression with pointer to base plus offset
    1395                                 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1396                                 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
    1397                                 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
    1398 
    1399                                 delete memberExpr;
    1400                                 return fieldLoc;
    1401                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
    1402                                 // union members are all at offset zero, so build appropriately-dereferenced variable
    1403                                 Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
    1404                                 delete memberExpr;
    1405                                 return derefdVar;
    1406                         } else return memberExpr;
    1407                 }
    1408 
    1409                 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
    1410                         // mutate, exiting early if no longer OffsetofExpr
    1411                         Expression *expr = Mutator::mutate( offsetofExpr );
    1412                         offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
    1413                         if ( ! offsetofExpr ) return expr;
    1414 
    1415                         // only mutate expressions for polymorphic structs/unions
    1416                         Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
    1417                         if ( ! ty ) return offsetofExpr;
    1418 
    1419                         if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    1420                                 // replace offsetof expression by index into offset array
    1421                                 long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );
    1422                                 if ( i == -1 ) return offsetofExpr;
    1423 
    1424                                 Expression *offsetInd = makeOffsetIndex( ty, i );
    1425                                 delete offsetofExpr;
    1426                                 return offsetInd;
    1427                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
    1428                                 // all union members are at offset zero
    1429                                 delete offsetofExpr;
    1430                                 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );
    1431                         } else return offsetofExpr;
     1341                        // add offset to deref'd variable
     1342                        UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1343                        fieldLoc->get_args().push_back( derefdVar );
     1344                        fieldLoc->get_args().push_back( fieldOffset );
     1345
     1346                        delete memberExpr;
     1347                        return fieldLoc;
    14321348                }
    14331349
Note: See TracChangeset for help on using the changeset viewer.