Changes in src/GenPoly/Box.cc [e16294d:ba3706f]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
re16294d rba3706f 163 163 void premutate( DeclStmt *declStmt ); 164 164 Expression *postmutate( MemberExpr *memberExpr ); 165 void premutate( AddressExpr *addrExpr );166 Expression *postmutate( AddressExpr *addrExpr );167 165 Expression *postmutate( SizeofExpr *sizeofExpr ); 168 166 Expression *postmutate( AlignofExpr *alignofExpr ); … … 184 182 /// change the type of generic aggregate members to char[] 185 183 void mutateMembers( AggregateDecl * aggrDecl ); 186 /// returns the calculated sizeof expression for ty, or nullptr for use C sizeof()187 Expression* genSizeof( Type* ty );188 184 189 185 /// Enters a new scope for type-variables, adding the type variables from ty … … 197 193 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 198 194 UniqueName bufNamer; ///< Namer for VLA buffers 199 Expression * addrMember = nullptr; ///< AddressExpr argument is MemberExpr?200 195 }; 201 196 … … 220 215 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 221 216 bool seenIntrinsic = false; 222 SemanticError Exceptionerrors;217 SemanticError errors; 223 218 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 224 219 try { … … 233 228 assert( *i ); 234 229 } // if 235 } catch( SemanticErrorException &e ) { 230 } catch( SemanticError &e ) { 231 e.set_location( (*i)->location ); 236 232 errors.append( e ); 237 233 } // try … … 306 302 Expression *makeOp( const std::string &name, Expression *arg ) { 307 303 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 308 expr-> args.push_back( arg );304 expr->get_args().push_back( arg ); 309 305 return expr; 310 306 } … … 313 309 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) { 314 310 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 315 expr-> args.push_back( lhs );316 expr-> args.push_back( rhs );311 expr->get_args().push_back( lhs ); 312 expr->get_args().push_back( rhs ); 317 313 return expr; 318 314 } … … 320 316 /// Returns the dereference of a local pointer variable 321 317 Expression *derefVar( ObjectDecl *var ) { 322 return UntypedExpr::createDeref(new VariableExpr( var ) );318 return makeOp( "*?", new VariableExpr( var ) ); 323 319 } 324 320 … … 384 380 unsigned long n_members = 0; 385 381 bool firstMember = true; 386 for ( Declaration* member : structDecl->get_members()) {387 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );382 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) { 383 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 388 384 assert( dwt ); 389 385 Type *memberType = dwt->get_type(); … … 580 576 } 581 577 } else { 582 SemanticError( argBaseType, "Cannot pass non-struct type for generic struct: ");578 throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType ); 583 579 } 584 580 } … … 602 598 } else { 603 599 // xxx - should this be an assertion? 604 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ));600 throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr ); 605 601 } // if 606 602 } // if … … 835 831 if ( ! isPolyType( arg->get_type() ) ) { 836 832 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 837 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 838 deref->result = arg->get_type()->clone(); 839 deref->result->set_lvalue( true ); 833 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 834 deref->set_result( arg->get_type()->clone() ); 840 835 return deref; 841 836 } // if … … 992 987 993 988 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) { 994 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr-> function) ) {995 if ( varExpr-> var->linkage== LinkageSpec::Intrinsic ) {996 if ( varExpr-> var->name== "?[?]" ) {989 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) { 990 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 991 if ( varExpr->get_var()->get_name() == "?[?]" ) { 997 992 assert( appExpr->result ); 998 993 assert( appExpr->get_args().size() == 2 ); 999 Type *baseType1 = isPolyPtr( appExpr-> args.front()->result, scopeTyVars, env );1000 Type *baseType2 = isPolyPtr( appExpr-> args.back()->result, scopeTyVars, env );994 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); 995 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env ); 1001 996 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 1002 997 UntypedExpr *ret = 0; … … 1179 1174 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1180 1175 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1181 if ( name-> name== "*?" ) {1176 if ( name->get_name() == "*?" ) { 1182 1177 Expression *ret = expr->args.front(); 1183 1178 expr->args.clear(); … … 1192 1187 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1193 1188 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1194 assert( addrExpr-> arg->result && ! addrExpr->arg->result->isVoid() );1189 assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() ); 1195 1190 1196 1191 bool needs = false; 1197 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr-> arg) ) {1198 if ( expr->result && isPolyType( expr-> result, scopeTyVars, env ) ) {1199 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr-> function) ) {1200 if ( name-> name== "*?" ) {1201 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr-> args.front() ) ) {1202 assert( appExpr-> function->result );1203 FunctionType *function = getFunctionType( appExpr-> function->result);1192 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1193 if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1194 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1195 if ( name->get_name() == "*?" ) { 1196 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 1197 assert( appExpr->get_function()->result ); 1198 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 1204 1199 assert( function ); 1205 1200 needs = needsAdapter( function, scopeTyVars ); … … 1211 1206 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1212 1207 // out of the if condition. 1213 addrExpr->arg = addrExpr-> arg->acceptMutator( *visitor );1208 addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor ); 1214 1209 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1215 bool polytype = isPolyType( addrExpr-> arg->result, scopeTyVars, env );1210 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); 1216 1211 if ( polytype || needs ) { 1217 Expression *ret = addrExpr-> arg;1218 delete ret-> result;1219 ret-> result = addrExpr->result->clone();1220 addrExpr-> arg = nullptr;1212 Expression *ret = addrExpr->get_arg(); 1213 delete ret->get_result(); 1214 ret->set_result( addrExpr->get_result()->clone() ); 1215 addrExpr->set_arg( 0 ); 1221 1216 delete addrExpr; 1222 1217 return ret; … … 1255 1250 1256 1251 void Pass2::addAdapters( FunctionType *functionType ) { 1257 std::list< DeclarationWithType *> ¶mList = functionType-> parameters;1252 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 1258 1253 std::list< FunctionType *> functions; 1259 1254 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { … … 1276 1271 1277 1272 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 1278 FunctionType * ftype = functionDecl-> type;1279 if ( ! ftype-> returnVals.empty() && functionDecl->statements) {1280 if ( ! isPrefix( functionDecl-> name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors1281 assert( ftype-> returnVals.size() == 1 );1282 DeclarationWithType * retval = ftype-> returnVals.front();1283 if ( retval-> name== "" ) {1284 retval-> name = "_retval";1273 FunctionType * ftype = functionDecl->get_functionType(); 1274 if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) { 1275 if ( ! isPrefix( functionDecl->get_name(), "_thunk" ) && ! isPrefix( functionDecl->get_name(), "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors 1276 assert( ftype->get_returnVals().size() == 1 ); 1277 DeclarationWithType * retval = ftype->get_returnVals().front(); 1278 if ( retval->get_name() == "" ) { 1279 retval->set_name( "_retval" ); 1285 1280 } 1286 functionDecl-> statements->kids.push_front( new DeclStmt( retval ) );1281 functionDecl->get_statements()->get_kids().push_front( new DeclStmt( retval ) ); 1287 1282 DeclarationWithType * newRet = retval->clone(); // for ownership purposes 1288 ftype-> returnVals.front() = newRet;1283 ftype->get_returnVals().front() = newRet; 1289 1284 } 1290 1285 } 1291 1286 // errors should have been caught by this point, remove initializers from parameters to allow correct codegen of default arguments 1292 for ( Declaration * param : functionDecl-> type->parameters) {1287 for ( Declaration * param : functionDecl->get_functionType()->get_parameters() ) { 1293 1288 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) { 1294 delete obj-> init;1295 obj-> init = nullptr;1289 delete obj->get_init(); 1290 obj->set_init( nullptr ); 1296 1291 } 1297 1292 } … … 1559 1554 // only mutate member expressions for polymorphic types 1560 1555 int tyDepth; 1561 Type *objectType = hasPolyBase( memberExpr-> aggregate->result, scopeTyVars, &tyDepth );1556 Type *objectType = hasPolyBase( memberExpr->get_aggregate()->get_result(), scopeTyVars, &tyDepth ); 1562 1557 if ( ! objectType ) return memberExpr; 1563 1558 findGeneric( objectType ); // ensure layout for this type is available 1564 1559 1565 1560 // replace member expression with dynamically-computed layout expression 1566 Expression *newMemberExpr = nullptr;1561 Expression *newMemberExpr = 0; 1567 1562 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1568 1563 // look up offset index 1569 long i = findMember( memberExpr-> member, structType->baseStruct->members);1564 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() ); 1570 1565 if ( i == -1 ) return memberExpr; 1571 1566 1572 1567 // replace member expression with pointer to base plus offset 1573 1568 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) ); 1574 Expression * aggr = memberExpr-> aggregate->clone();1575 delete aggr-> env; // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it1576 aggr-> env = nullptr;1569 Expression * aggr = memberExpr->get_aggregate()->clone(); 1570 delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it 1571 aggr->set_env( nullptr ); 1577 1572 fieldLoc->get_args().push_back( aggr ); 1578 1573 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) ); 1579 fieldLoc->set_result( memberExpr-> result->clone() );1574 fieldLoc->set_result( memberExpr->get_result()->clone() ); 1580 1575 newMemberExpr = fieldLoc; 1581 1576 } else if ( dynamic_cast< UnionInstType* >( objectType ) ) { 1582 1577 // union members are all at offset zero, so just use the aggregate expr 1583 Expression * aggr = memberExpr-> aggregate->clone();1584 delete aggr-> env; // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it1585 aggr-> env= nullptr;1578 Expression * aggr = memberExpr->get_aggregate()->clone(); 1579 delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it 1580 aggr->set_env( nullptr ); 1586 1581 newMemberExpr = aggr; 1587 newMemberExpr-> result = memberExpr->result->clone();1582 newMemberExpr->set_result( memberExpr->get_result()->clone() ); 1588 1583 } else return memberExpr; 1589 1584 assert( newMemberExpr ); 1590 1585 1591 // Must apply the generic substitution to the member type to handle cases where the member is a generic parameter substituted by a known concrete type, e.g. 1592 // forall(otype T) struct Box { T x; } 1593 // forall(otype T) f() { 1594 // Box(T *) b; b.x; 1595 // } 1596 // TODO: memberExpr->result should be exactly memberExpr->member->get_type() after substitution, so it doesn't seem like it should be necessary to apply the substitution manually. For some reason this is not currently the case. This requires more investigation. 1597 Type *memberType = memberExpr->member->get_type()->clone(); 1598 TypeSubstitution sub = objectType->genericSubstitution(); 1599 sub.apply( memberType ); 1586 Type *memberType = memberExpr->get_member()->get_type(); 1600 1587 if ( ! isPolyType( memberType, scopeTyVars ) ) { 1601 1588 // Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue … … 1605 1592 } 1606 1593 1607 delete memberType;1608 1594 delete memberExpr; 1609 1595 return newMemberExpr; 1610 1596 } 1611 1597 1612 void PolyGenericCalculator::premutate( AddressExpr * addrExpr ) {1613 GuardValue( addrMember );1614 // is the argument a MemberExpr before mutating?1615 addrMember = dynamic_cast< MemberExpr * >( addrExpr->arg );1616 }1617 1618 Expression * PolyGenericCalculator::postmutate( AddressExpr * addrExpr ) {1619 if ( addrMember && addrMember != addrExpr->arg ) {1620 // arg was a MemberExpr and has been mutated1621 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( addrExpr->arg ) ) {1622 if ( InitTweak::getFunctionName( untyped ) == "?+?" ) {1623 // MemberExpr was converted to pointer+offset, and it is not valid C to take the address of an addition, so strip the address-of1624 // TODO: should addrExpr->arg->result be changed to addrExpr->result?1625 Expression * ret = addrExpr->arg;1626 addrExpr->arg = nullptr;1627 std::swap( addrExpr->env, ret->env );1628 delete addrExpr;1629 return ret;1630 }1631 }1632 }1633 return addrExpr;1634 }1635 1636 1598 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1637 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, nullptr, type, init );1599 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init ); 1638 1600 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 1639 1601 return newObj; … … 1749 1711 } 1750 1712 1751 Expression * PolyGenericCalculator::genSizeof( Type* ty ) {1752 if ( ArrayType * aty = dynamic_cast<ArrayType *>(ty) ) {1753 // generate calculated size for possibly generic array1754 Expression * sizeofBase = genSizeof( aty->get_base() );1755 if ( ! sizeofBase ) return nullptr;1756 Expression * dim = aty->get_dimension();1757 aty->set_dimension( nullptr );1758 return makeOp( "?*?", sizeofBase, dim );1759 } else if ( findGeneric( ty ) ) {1760 // generate calculated size for generic type1761 return new NameExpr( sizeofName( mangleType( ty ) ) );1762 } else return nullptr;1763 }1764 1765 1713 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 1766 Type *ty = sizeofExpr->get_isType() ? 1767 sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1768 1769 Expression * gen = genSizeof( ty ); 1770 if ( gen ) { 1714 Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1715 if ( findGeneric( ty ) ) { 1716 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) ); 1771 1717 delete sizeofExpr; 1772 return gen; 1773 } else return sizeofExpr; 1718 return ret; 1719 } 1720 return sizeofExpr; 1774 1721 } 1775 1722
Note:
See TracChangeset
for help on using the changeset viewer.