Changeset 5600747 for src/GenPoly/Box.cc
- Timestamp:
- Mar 8, 2018, 9:23:32 AM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 4c11fce, ab0203df
- Parents:
- e5d4e5c (diff), fb11446e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
re5d4e5c r5600747 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 ); … … 193 195 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 194 196 UniqueName bufNamer; ///< Namer for VLA buffers 197 Expression * addrMember = nullptr; ///< AddressExpr argument is MemberExpr? 195 198 }; 196 199 … … 1174 1177 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1175 1178 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1176 if ( name-> get_name()== "*?" ) {1179 if ( name->name == "*?" ) { 1177 1180 Expression *ret = expr->args.front(); 1178 1181 expr->args.clear(); … … 1187 1190 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1188 1191 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1189 assert( addrExpr-> get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );1192 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); 1190 1193 1191 1194 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());1195 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 1196 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1197 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1198 if ( name->name == "*?" ) { 1199 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1200 assert( appExpr->function->result ); 1201 FunctionType *function = getFunctionType( appExpr->function->result ); 1199 1202 assert( function ); 1200 1203 needs = needsAdapter( function, scopeTyVars ); … … 1206 1209 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1207 1210 // out of the if condition. 1208 addrExpr->arg = addrExpr-> get_arg()->acceptMutator( *visitor );1211 addrExpr->arg = addrExpr->arg->acceptMutator( *visitor ); 1209 1212 // ... 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 );1213 bool polytype = isPolyType( addrExpr->arg->result, scopeTyVars, env ); 1211 1214 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 );1215 Expression *ret = addrExpr->arg; 1216 delete ret->result; 1217 ret->result = addrExpr->result->clone(); 1218 addrExpr->arg = nullptr; 1216 1219 delete addrExpr; 1217 1220 return ret; … … 1250 1253 1251 1254 void Pass2::addAdapters( FunctionType *functionType ) { 1252 std::list< DeclarationWithType *> ¶mList = functionType-> get_parameters();1255 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1253 1256 std::list< FunctionType *> functions; 1254 1257 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { … … 1271 1274 1272 1275 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" );1276 FunctionType * ftype = functionDecl->type; 1277 if ( ! ftype->returnVals.empty() && functionDecl->statements ) { 1278 if ( ! isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors 1279 assert( ftype->returnVals.size() == 1 ); 1280 DeclarationWithType * retval = ftype->returnVals.front(); 1281 if ( retval->name == "" ) { 1282 retval->name = "_retval"; 1280 1283 } 1281 functionDecl-> get_statements()->get_kids().push_front( new DeclStmt( retval ) );1284 functionDecl->statements->kids.push_front( new DeclStmt( retval ) ); 1282 1285 DeclarationWithType * newRet = retval->clone(); // for ownership purposes 1283 ftype-> get_returnVals().front() = newRet;1286 ftype->returnVals.front() = newRet; 1284 1287 } 1285 1288 } 1286 1289 // 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()) {1290 for ( Declaration * param : functionDecl->type->parameters ) { 1288 1291 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) { 1289 delete obj-> get_init();1290 obj-> set_init( nullptr );1292 delete obj->init; 1293 obj->init = nullptr; 1291 1294 } 1292 1295 } … … 1584 1587 assert( newMemberExpr ); 1585 1588 1586 Type *memberType = memberExpr->member->get_type(); 1589 // 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. 1590 // forall(otype T) struct Box { T x; } 1591 // forall(otype T) f() { 1592 // Box(T *) b; b.x; 1593 // } 1594 // 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. 1595 Type *memberType = memberExpr->member->get_type()->clone(); 1596 TypeSubstitution sub = objectType->genericSubstitution(); 1597 sub.apply( memberType ); 1587 1598 if ( ! isPolyType( memberType, scopeTyVars ) ) { 1588 1599 // 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 1603 } 1593 1604 1605 delete memberType; 1594 1606 delete memberExpr; 1595 1607 return newMemberExpr; 1608 } 1609 1610 void PolyGenericCalculator::premutate( AddressExpr * addrExpr ) { 1611 GuardValue( addrMember ); 1612 // is the argument a MemberExpr before mutating? 1613 addrMember = dynamic_cast< MemberExpr * >( addrExpr->arg ); 1614 } 1615 1616 Expression * PolyGenericCalculator::postmutate( AddressExpr * addrExpr ) { 1617 if ( addrMember && addrMember != addrExpr->arg ) { 1618 // arg was a MemberExpr and has been mutated 1619 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( addrExpr->arg ) ) { 1620 if ( InitTweak::getFunctionName( untyped ) == "?+?" ) { 1621 // MemberExpr was converted to pointer+offset, and it is not valid C to take the address of an addition, so strip the address-of 1622 // TODO: should addrExpr->arg->result be changed to addrExpr->result? 1623 Expression * ret = addrExpr->arg; 1624 addrExpr->arg = nullptr; 1625 std::swap( addrExpr->env, ret->env ); 1626 delete addrExpr; 1627 return ret; 1628 } 1629 } 1630 } 1631 return addrExpr; 1596 1632 } 1597 1633
Note: See TracChangeset
for help on using the changeset viewer.