Changeset bc07190 for src/ResolvExpr
- Timestamp:
- Jun 29, 2024, 7:33:28 AM (19 months ago)
- Branches:
- master
- Children:
- 011c29e
- Parents:
- 62a38e7 (diff), 115ac1ce (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. - Location:
- src/ResolvExpr
- Files:
-
- 5 edited
-
CandidateFinder.cpp (modified) (4 diffs)
-
CastCost.cpp (modified) (4 diffs)
-
CommonType.cpp (modified) (2 diffs)
-
ConversionCost.cpp (modified) (6 diffs)
-
Unify.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CandidateFinder.cpp
r62a38e7 rbc07190 698 698 void postvisit( const ast::CountExpr * countExpr ); 699 699 700 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,701 const ast::EnumInstType * dst702 , const ast::Expr * expr, Cost minCost );703 704 700 void postvisit( const ast::InitExpr * ) { 705 701 assertf( false, "CandidateFinder should never see a resolved InitExpr." ); … … 1213 1209 } 1214 1210 1215 // src is a subset of dst1216 const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src,1217 const ast::EnumInstType * dst,1218 const ast::Expr * expr,1219 Cost minCost ) {1220 1221 auto srcDecl = src->base;1222 auto dstDecl = dst->base;1223 1224 if (srcDecl->name == dstDecl->name) return expr;1225 1226 for (auto& dstChild: dstDecl->inlinedDecl) {1227 Cost c = castCost(src, dstChild, false, symtab, tenv);1228 ast::CastExpr * castToDst;1229 if (c<minCost) {1230 unsigned offset = dstDecl->calChildOffset(dstChild.get());1231 if (offset > 0) {1232 auto untyped = ast::UntypedExpr::createCall(1233 expr->location,1234 "?+?",1235 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),1236 ast::ConstantExpr::from_int(expr->location, offset)});1237 CandidateFinder finder(context, tenv);1238 finder.find( untyped );1239 CandidateList winners = findMinCost( finder.candidates );1240 CandidateRef & choice = winners.front();1241 // choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );1242 choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);1243 // castToDst = new ast::CastExpr(choice->expr, dstChild);1244 castToDst = new ast::CastExpr(1245 makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),1246 dst);1247 1248 } else {1249 castToDst = new ast::CastExpr( expr, dst );1250 }1251 return castToDst;1252 }1253 }1254 SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);1255 return nullptr;1256 }1257 1258 1211 void Finder::postvisit( const ast::CastExpr * castExpr ) { 1259 1212 ast::ptr< ast::Type > toType = castExpr->result; … … 1309 1262 auto argAsEnum = cand->expr->result.as<ast::EnumInstType>(); 1310 1263 auto toAsEnum = toType.as<ast::EnumInstType>(); 1311 if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) { 1312 ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost); 1264 if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) { 1265 CandidateFinder subFinder(context, tenv); 1266 ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost); 1313 1267 cand->expr = offsetExpr; 1314 1268 } … … 2193 2147 expr->location, 2194 2148 "?+?", 2195 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ), 2196 ast::ConstantExpr::from_int(expr->location, offset)}); 2149 { new ast::CastExpr( expr->location, 2150 expr, 2151 new ast::BasicType(ast::BasicKind::SignedInt), 2152 ast::GeneratedFlag::ExplicitCast ), 2153 ast::ConstantExpr::from_int(expr->location, offset)} ); 2197 2154 CandidateFinder finder(context, env); 2198 2155 finder.find( untyped ); -
src/ResolvExpr/CastCost.cpp
r62a38e7 rbc07190 53 53 void postvisit( const ast::EnumInstType * enumInst ) { 54 54 cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env ); 55 if ( enumInst->base->isTyped() ) { 56 auto baseConversionCost = 57 castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env ); 58 cost = baseConversionCost < cost? baseConversionCost: cost; 59 } 60 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 61 Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 62 intCost.incSafe(); 63 cost = intCost < cost? intCost: cost; 55 64 } 56 65 … … 63 72 cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env ); 64 73 if ( Cost::unsafe < cost ) { 65 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 66 // Always explict cast only for typed enum 67 if (enumInst->base->isTyped) cost = Cost::unsafe; 74 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 75 cost = Cost::unsafe; 68 76 } 69 77 } … … 74 82 cost = conversionCost( zero, dst, srcIsLvalue, symtab, env ); 75 83 if ( Cost::unsafe < cost ) { 76 if ( auto enumInst =dynamic_cast<const ast::EnumInstType *>(dst)) {77 if (enumInst->base->isTyped)cost = Cost::unsafe;84 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 85 cost = Cost::unsafe; 78 86 } 79 87 } … … 83 91 cost = conversionCost( one, dst, srcIsLvalue, symtab, env ); 84 92 if ( Cost::unsafe < cost ) { 85 if ( auto enumInst =dynamic_cast<const ast::EnumInstType *>(dst)) {86 if (enumInst->base->isTyped)cost = Cost::unsafe;93 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 94 cost = Cost::unsafe; 87 95 } 88 96 } -
src/ResolvExpr/CommonType.cpp
r62a38e7 rbc07190 386 386 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 387 387 const ast::EnumDecl* enumDecl = enumInst->base; 388 if ( !enumDecl-> base) {388 if ( !enumDecl->isCfa ) { 389 389 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; 390 390 if ( … … 642 642 const ast::EnumDecl* argDecl = argAsEnumInst->base; 643 643 if (argDecl->isSubTypeOf(paramDecl)) result = param; 644 } else if ( param->base && !param->base->is Typed) {644 } else if ( param->base && !param->base->isCfa ) { 645 645 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 646 646 result = commonType( basicType, type2, tenv, need, have, open, widen); -
src/ResolvExpr/ConversionCost.cpp
r62a38e7 rbc07190 162 162 Cost conversionCost( 163 163 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env 165 165 ) { 166 166 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 235 235 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost ); 236 236 } 237 if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) { 238 if (srcAsInst->base && !srcAsInst->base->isCfa) { 239 static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt ); 240 return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost ); 241 } 242 } 237 243 } else { 238 244 assert( -1 == diff ); 239 245 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 240 246 assert( dstAsRef ); 241 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) { 247 auto dstBaseType = dstAsRef->base; 248 const ast::Type * newSrc = src; 249 if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) { 250 newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt ); 251 } 252 if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) { 242 253 if ( srcIsLvalue ) { 243 254 if ( src->qualifiers == dstAsRef->base->qualifiers ) { … … 284 295 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 285 296 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 286 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {287 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {288 cost = Cost:: unsafe;297 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 298 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 299 cost = Cost::safe; 289 300 } 290 301 } … … 366 377 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 367 378 cost = enumCastCost(inst, dstInst, symtab, env); 368 return; 369 } 370 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 371 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 372 if ( !inst->base->isTyped ) { 373 if ( cost < Cost::unsafe ) { 374 cost.incSafe(); 375 } 376 return; 377 } 378 cost.incUnsafe(); 379 } else if ( !inst->base->isCfa ) { 380 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 381 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 382 } 383 // cost.incUnsafe(); 379 384 } 380 385 … … 454 459 // assuming 0p is supposed to be used for pointers? 455 460 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 456 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {457 cost = Cost:: unsafe;461 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 462 cost = Cost::safe; 458 463 } 459 464 } … … 475 480 } 476 481 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 477 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {478 cost = Cost:: unsafe;482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 483 cost = Cost::safe; 479 484 } 480 485 } -
src/ResolvExpr/Unify.cpp
r62a38e7 rbc07190 276 276 void postvisit( const ast::VoidType * ) { 277 277 result = dynamic_cast< const ast::VoidType * >( type2 ); 278 // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());279 ;280 278 } 281 279 … … 284 282 result = basic->kind == basic2->kind; 285 283 } 286 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());287 284 } 288 285 … … 293 290 noWiden()); 294 291 } 295 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());296 292 } 297 293 … … 312 308 result = unifyExact( 313 309 array->base, array2->base, tenv, need, have, open, noWiden()); 314 // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());315 310 } 316 311 … … 607 602 608 603 result = unifyList( types, types2, tenv, need, have, open ); 609 // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());610 604 } 611 605 612 606 void postvisit( const ast::VarArgsType * ) { 613 607 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 614 // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());615 608 } 616 609 617 610 void postvisit( const ast::ZeroType * ) { 618 611 result = dynamic_cast< const ast::ZeroType * >( type2 ); 619 // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());620 612 } 621 613 622 614 void postvisit( const ast::OneType * ) { 623 615 result = dynamic_cast< const ast::OneType * >( type2 ); 624 // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());625 616 } 626 617 };
Note:
See TracChangeset
for help on using the changeset viewer.