Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rb4cd03b7 rb10c9959  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Feb 05 12:23:10 2016
    13 // Update Count     : 280
     12// Last Modified On : Fri Dec 18 14:53:08 2015
     13// Update Count     : 217
    1414//
    1515
     
    123123                };
    124124
    125                 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
     126                /// also fixes offsetof expressions.
    126127                class MemberExprFixer : public PolyMutator {
    127128                  public:
     
    136137                        virtual Type *mutate( FunctionType *funcType );
    137138                        virtual Expression *mutate( MemberExpr *memberExpr );
     139                        virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    138140                };
    139 
     141               
    140142                /// 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
    141143                class Pass3 : public PolyMutator {
     
    176178                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
    177179                                        }
    178 
     180                                       
    179181                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
    180182                                        assert( *i );
     
    284286                                }
    285287                        }
    286 
     288                       
    287289                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    288290                                doBeginScope();
     
    318320                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    319321                                } // for
    320 
     322                               
    321323                                AdapterMap & adapters = Pass1::adapters.top();
    322324                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    371373                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
    372374                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    373 
     375                       
    374376                        // make a new temporary array
    375377                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     
    395397                        return new VariableExpr( arrayTemp );
    396398                }
    397 
     399               
    398400                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    399401                        // pass size/align for type variables
     
    491493                        }
    492494                }
    493 
     495               
    494496                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
    495497                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     
    529531                        std::string adapterName = makeAdapterName( mangleName );
    530532
    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 ) );
     533                        appExpr->get_args().push_front( appExpr->get_function() );
    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.
    564561                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    565                         Type * newType = formal->clone();
    566                         if ( getFunctionType( newType ) ) {
    567                                 newType = ScrubTyVars::scrub( newType, 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() ) {
    568568                                actual = new CastExpr( actual, newType );
     569                        } else {
     570                                delete newType;
    569571                        } // if
    570572                }
     
    987989                }
    988990
     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               
    9891000                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    9901001                        if ( retval && returnStmt->get_expr() ) {
     
    10021013
    10031014                                // find assignment operator for (polymorphic) return type
    1004                                 DeclarationWithType *assignDecl = 0;
     1015                                ApplicationExpr *assignExpr = 0;
    10051016                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1017                                        // find assignment operator for type variable
    10061018                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10071019                                        if ( assignIter == assignOps.end() ) {
    10081020                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10091021                                        } // if
    1010                                         assignDecl = assignIter->second;
     1022                                        assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    10111023                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1024                                        // find assignment operator for generic type
    10121025                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10131026                                        if ( assignIter == scopedAssignOps.end() ) {
    10141027                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10151028                                        }
     1029
     1030                                        // wrap it up in an application expression
    10161031                                        DeclarationWithType *functionDecl = assignIter->second;
    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() );
     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                                        }
    10211073                                }
    1022                                 assert( assignDecl );
     1074                                assert( assignExpr );
    10231075
    10241076                                // replace return statement with appropriate assignment to out parameter
    1025                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10261077                                Expression *retParm = new NameExpr( retval->get_name() );
    10271078                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    12831334                }
    12841335
     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 ) {
     1340                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1341
     1342                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1343                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1344                                        else continue;
     1345                                } else return i;
     1346                        }
     1347                        return -1;
     1348                }
     1349
     1350                /// Returns an index expression into the offset array for a type
     1351                Expression *makeOffsetIndex( Type *objectType, long i ) {
     1352                        std::stringstream offset_namer;
     1353                        offset_namer << i;
     1354                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1355                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1356                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1357                        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 ) {
     1364                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     1365                                derefExpr->get_args().push_back( derefdVar );
     1366                                derefdVar = derefExpr;
     1367                        }
     1368                        return derefdVar;
     1369                }
     1370               
    12851371                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    12861372                        // mutate, exiting early if no longer MemberExpr
     
    13011387                        if ( ! objectType ) return memberExpr;
    13021388
    1303                         // get base aggregate for type so members can be looked up
    1304                         AggregateDecl *memberBase = 0;
    13051389                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    1306                                 memberBase = structType->get_baseStruct();
     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;
    13071401                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
    1308                                 memberBase = unionType->get_baseUnion();
     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;
    13091406                        } 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 ) {
    1317                                 if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
    1318 
    1319                                 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1320                                         if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
    1321                                         else continue;
    1322                                 } else break;
    1323                         }
    1324                         if ( decl == baseDecls.end() ) return memberExpr;
    1325 
    1326                         // replace member expression with pointer to base plus offset
    1327                         // get offset for field
    1328                         std::stringstream offset_namer;
    1329                         offset_namer << i;
    1330                         ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
    1331                         UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    1332                         fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    1333                         fieldOffset->get_args().push_back( fieldIndex );
    1334                         // build appropriately-dereferenced variable
    1335                         Expression *derefdVar = varExpr->clone();
    1336                         for ( int i = 1; i < varDepth; ++i ) {
    1337                                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    1338                                 derefExpr->get_args().push_back( derefdVar );
    1339                                 derefdVar = derefExpr;
    1340                         }
    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;
     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;
    13481432                }
    13491433
Note: See TracChangeset for help on using the changeset viewer.