Changes in src/GenPoly/Box.cc [ba3706f:e16294d]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rba3706f re16294d 163 163 void premutate( DeclStmt *declStmt ); 164 164 Expression *postmutate( MemberExpr *memberExpr ); 165 void premutate( AddressExpr *addrExpr ); 166 Expression *postmutate( AddressExpr *addrExpr ); 165 167 Expression *postmutate( SizeofExpr *sizeofExpr ); 166 168 Expression *postmutate( AlignofExpr *alignofExpr ); … … 182 184 /// change the type of generic aggregate members to char[] 183 185 void mutateMembers( AggregateDecl * aggrDecl ); 186 /// returns the calculated sizeof expression for ty, or nullptr for use C sizeof() 187 Expression* genSizeof( Type* ty ); 184 188 185 189 /// Enters a new scope for type-variables, adding the type variables from ty … … 193 197 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 194 198 UniqueName bufNamer; ///< Namer for VLA buffers 199 Expression * addrMember = nullptr; ///< AddressExpr argument is MemberExpr? 195 200 }; 196 201 … … 215 220 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 216 221 bool seenIntrinsic = false; 217 SemanticError errors;222 SemanticErrorException errors; 218 223 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 219 224 try { … … 228 233 assert( *i ); 229 234 } // if 230 } catch( SemanticError &e ) { 231 e.set_location( (*i)->location ); 235 } catch( SemanticErrorException &e ) { 232 236 errors.append( e ); 233 237 } // try … … 302 306 Expression *makeOp( const std::string &name, Expression *arg ) { 303 307 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 304 expr-> get_args().push_back( arg );308 expr->args.push_back( arg ); 305 309 return expr; 306 310 } … … 309 313 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) { 310 314 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 311 expr-> get_args().push_back( lhs );312 expr-> get_args().push_back( rhs );315 expr->args.push_back( lhs ); 316 expr->args.push_back( rhs ); 313 317 return expr; 314 318 } … … 316 320 /// Returns the dereference of a local pointer variable 317 321 Expression *derefVar( ObjectDecl *var ) { 318 return makeOp( "*?",new VariableExpr( var ) );322 return UntypedExpr::createDeref( new VariableExpr( var ) ); 319 323 } 320 324 … … 380 384 unsigned long n_members = 0; 381 385 bool firstMember = true; 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 );386 for ( Declaration* member : structDecl->get_members() ) { 387 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 384 388 assert( dwt ); 385 389 Type *memberType = dwt->get_type(); … … 576 580 } 577 581 } else { 578 throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType);582 SemanticError( argBaseType, "Cannot pass non-struct type for generic struct: " ); 579 583 } 580 584 } … … 598 602 } else { 599 603 // xxx - should this be an assertion? 600 throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr);604 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) ); 601 605 } // if 602 606 } // if … … 831 835 if ( ! isPolyType( arg->get_type() ) ) { 832 836 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 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() ); 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 ); 835 840 return deref; 836 841 } // if … … 987 992 988 993 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) { 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()== "?[?]" ) {994 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->function ) ) { 995 if ( varExpr->var->linkage == LinkageSpec::Intrinsic ) { 996 if ( varExpr->var->name == "?[?]" ) { 992 997 assert( appExpr->result ); 993 998 assert( appExpr->get_args().size() == 2 ); 994 Type *baseType1 = isPolyPtr( appExpr-> get_args().front()->get_result(), scopeTyVars, env );995 Type *baseType2 = isPolyPtr( appExpr-> get_args().back()->get_result(), scopeTyVars, env );999 Type *baseType1 = isPolyPtr( appExpr->args.front()->result, scopeTyVars, env ); 1000 Type *baseType2 = isPolyPtr( appExpr->args.back()->result, scopeTyVars, env ); 996 1001 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 997 1002 UntypedExpr *ret = 0; … … 1174 1179 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1175 1180 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1176 if ( name-> get_name()== "*?" ) {1181 if ( name->name == "*?" ) { 1177 1182 Expression *ret = expr->args.front(); 1178 1183 expr->args.clear(); … … 1187 1192 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1188 1193 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1189 assert( addrExpr-> get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );1194 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); 1190 1195 1191 1196 bool needs = false; 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());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 ); 1199 1204 assert( function ); 1200 1205 needs = needsAdapter( function, scopeTyVars ); … … 1206 1211 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1207 1212 // out of the if condition. 1208 addrExpr->arg = addrExpr-> get_arg()->acceptMutator( *visitor );1213 addrExpr->arg = addrExpr->arg->acceptMutator( *visitor ); 1209 1214 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1210 bool polytype = isPolyType( addrExpr-> get_arg()->get_result(), scopeTyVars, env );1215 bool polytype = isPolyType( addrExpr->arg->result, scopeTyVars, env ); 1211 1216 if ( polytype || needs ) { 1212 Expression *ret = addrExpr-> get_arg();1213 delete ret-> get_result();1214 ret-> set_result( addrExpr->get_result()->clone());1215 addrExpr-> set_arg( 0 );1217 Expression *ret = addrExpr->arg; 1218 delete ret->result; 1219 ret->result = addrExpr->result->clone(); 1220 addrExpr->arg = nullptr; 1216 1221 delete addrExpr; 1217 1222 return ret; … … 1250 1255 1251 1256 void Pass2::addAdapters( FunctionType *functionType ) { 1252 std::list< DeclarationWithType *> ¶mList = functionType-> get_parameters();1257 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1253 1258 std::list< FunctionType *> functions; 1254 1259 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { … … 1271 1276 1272 1277 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 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/dtors1276 assert( ftype-> get_returnVals().size() == 1 );1277 DeclarationWithType * retval = ftype-> get_returnVals().front();1278 if ( retval-> get_name()== "" ) {1279 retval-> set_name( "_retval" );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/dtors 1281 assert( ftype->returnVals.size() == 1 ); 1282 DeclarationWithType * retval = ftype->returnVals.front(); 1283 if ( retval->name == "" ) { 1284 retval->name = "_retval"; 1280 1285 } 1281 functionDecl-> get_statements()->get_kids().push_front( new DeclStmt( retval ) );1286 functionDecl->statements->kids.push_front( new DeclStmt( retval ) ); 1282 1287 DeclarationWithType * newRet = retval->clone(); // for ownership purposes 1283 ftype-> get_returnVals().front() = newRet;1288 ftype->returnVals.front() = newRet; 1284 1289 } 1285 1290 } 1286 1291 // errors should have been caught by this point, remove initializers from parameters to allow correct codegen of default arguments 1287 for ( Declaration * param : functionDecl-> get_functionType()->get_parameters()) {1292 for ( Declaration * param : functionDecl->type->parameters ) { 1288 1293 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) { 1289 delete obj-> get_init();1290 obj-> set_init( nullptr );1294 delete obj->init; 1295 obj->init = nullptr; 1291 1296 } 1292 1297 } … … 1554 1559 // only mutate member expressions for polymorphic types 1555 1560 int tyDepth; 1556 Type *objectType = hasPolyBase( memberExpr-> get_aggregate()->get_result(), scopeTyVars, &tyDepth );1561 Type *objectType = hasPolyBase( memberExpr->aggregate->result, scopeTyVars, &tyDepth ); 1557 1562 if ( ! objectType ) return memberExpr; 1558 1563 findGeneric( objectType ); // ensure layout for this type is available 1559 1564 1560 1565 // replace member expression with dynamically-computed layout expression 1561 Expression *newMemberExpr = 0;1566 Expression *newMemberExpr = nullptr; 1562 1567 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1563 1568 // look up offset index 1564 long i = findMember( memberExpr-> get_member(), structType->get_baseStruct()->get_members());1569 long i = findMember( memberExpr->member, structType->baseStruct->members ); 1565 1570 if ( i == -1 ) return memberExpr; 1566 1571 1567 1572 // replace member expression with pointer to base plus offset 1568 1573 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) ); 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 it1571 aggr-> set_env( nullptr );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 it 1576 aggr->env = nullptr; 1572 1577 fieldLoc->get_args().push_back( aggr ); 1573 1578 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) ); 1574 fieldLoc->set_result( memberExpr-> get_result()->clone() );1579 fieldLoc->set_result( memberExpr->result->clone() ); 1575 1580 newMemberExpr = fieldLoc; 1576 1581 } else if ( dynamic_cast< UnionInstType* >( objectType ) ) { 1577 1582 // union members are all at offset zero, so just use the aggregate expr 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 it1580 aggr-> set_env( nullptr );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 it 1585 aggr->env= nullptr; 1581 1586 newMemberExpr = aggr; 1582 newMemberExpr-> set_result( memberExpr->get_result()->clone());1587 newMemberExpr->result = memberExpr->result->clone(); 1583 1588 } else return memberExpr; 1584 1589 assert( newMemberExpr ); 1585 1590 1586 Type *memberType = memberExpr->get_member()->get_type(); 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 ); 1587 1600 if ( ! isPolyType( memberType, scopeTyVars ) ) { 1588 1601 // 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 … … 1592 1605 } 1593 1606 1607 delete memberType; 1594 1608 delete memberExpr; 1595 1609 return newMemberExpr; 1596 1610 } 1597 1611 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 mutated 1621 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-of 1624 // 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 1598 1636 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1599 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init );1637 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, nullptr, type, init ); 1600 1638 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 1601 1639 return newObj; … … 1711 1749 } 1712 1750 1751 Expression * PolyGenericCalculator::genSizeof( Type* ty ) { 1752 if ( ArrayType * aty = dynamic_cast<ArrayType *>(ty) ) { 1753 // generate calculated size for possibly generic array 1754 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 type 1761 return new NameExpr( sizeofName( mangleType( ty ) ) ); 1762 } else return nullptr; 1763 } 1764 1713 1765 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 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 ) ) ); 1766 Type *ty = sizeofExpr->get_isType() ? 1767 sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1768 1769 Expression * gen = genSizeof( ty ); 1770 if ( gen ) { 1717 1771 delete sizeofExpr; 1718 return ret; 1719 } 1720 return sizeofExpr; 1772 return gen; 1773 } else return sizeofExpr; 1721 1774 } 1722 1775
Note:
See TracChangeset
for help on using the changeset viewer.