Changeset f53acdf8 for src/ResolvExpr
- Timestamp:
- Jul 19, 2019, 2:16:01 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 4eb43fa
- Parents:
- 1f1c102 (diff), 8ac3b0e (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:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AdjustExprType.cc
r1f1c102 rf53acdf8 47 47 void premutate( OneType * ) { visit_children = false; } 48 48 49 Type * postmutate( ArrayType * arrayType );50 Type * postmutate( FunctionType * functionType );51 Type * postmutate( TypeInstType * aggregateUseType );49 Type * postmutate( ArrayType * arrayType ); 50 Type * postmutate( FunctionType * functionType ); 51 Type * postmutate( TypeInstType * aggregateUseType ); 52 52 53 53 private: … … 61 61 62 62 Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) { 63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 64 64 arrayType->base = nullptr; 65 65 delete arrayType; … … 72 72 73 73 Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) { 74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 75 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 76 76 return new PointerType{ Type::Qualifiers(), typeInst }; 77 77 } 78 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {79 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {78 } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) { 79 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) { 80 80 if ( tyDecl->get_kind() == TypeDecl::Ftype ) { 81 81 return new PointerType{ Type::Qualifiers(), typeInst }; … … 89 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type * newType = type->acceptMutator( adjuster );91 Type * newType = type->acceptMutator( adjuster ); 92 92 type = newType; 93 93 } … … 149 149 } // anonymous namespace 150 150 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 153 153 ) { 154 154 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; -
src/ResolvExpr/AlternativeFinder.cc
r1f1c102 rf53acdf8 336 336 } 337 337 338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 339 339 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 341 341 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 342 342 } // if … … 344 344 345 345 template< typename StructOrUnionType > 346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 347 347 std::list< Declaration* > members; 348 348 aggInst->lookup( name, members ); 349 349 350 350 for ( Declaration * decl : members ) { 351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 352 352 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 353 353 // can't construct in place and use vector::back … … 362 362 } 363 363 364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ) {364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) { 365 365 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 366 366 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 368 368 std::string tmp; 369 369 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 370 alternatives.push_back( Alternative{ 370 alternatives.push_back( Alternative{ 371 371 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 372 372 } // if … … 374 374 } 375 375 376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) { 377 377 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 378 378 } … … 475 475 } 476 476 477 // specialization cost of return types can't be accounted for directly, it disables 477 // specialization cost of return types can't be accounted for directly, it disables 478 478 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 479 479 // … … 1226 1226 // count one safe conversion for each value that is thrown away 1227 1227 thisCost.incSafe( discardedValues ); 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1230 1230 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1231 1231 inferParameters( newAlt, back_inserter( candidates ) ); … … 1328 1328 if ( sizeofExpr->get_isType() ) { 1329 1329 Type * newType = sizeofExpr->get_type()->clone(); 1330 alternatives.push_back( Alternative{ 1330 alternatives.push_back( Alternative{ 1331 1331 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1332 1332 } else { … … 1343 1343 Alternative &choice = winners.front(); 1344 1344 referenceToRvalueConversion( choice.expr, choice.cost ); 1345 alternatives.push_back( Alternative{ 1345 alternatives.push_back( Alternative{ 1346 1346 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1347 1347 } // if … … 1351 1351 if ( alignofExpr->get_isType() ) { 1352 1352 Type * newType = alignofExpr->get_type()->clone(); 1353 alternatives.push_back( Alternative{ 1353 alternatives.push_back( Alternative{ 1354 1354 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1355 1355 } else { … … 1366 1366 Alternative &choice = winners.front(); 1367 1367 referenceToRvalueConversion( choice.expr, choice.cost ); 1368 alternatives.push_back( Alternative{ 1368 alternatives.push_back( Alternative{ 1369 1369 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1370 1370 } // if … … 1377 1377 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1378 1378 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1379 alternatives.push_back( Alternative{ 1379 alternatives.push_back( Alternative{ 1380 1380 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1381 1381 renameTypes( alternatives.back().expr ); … … 1405 1405 1406 1406 namespace { 1407 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {1407 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1408 1408 // assume no polymorphism 1409 1409 // assume no implicit conversions 1410 assert( function-> get_parameters().size() == 1 );1410 assert( function->parameters.size() == 1 ); 1411 1411 PRINT( 1412 1412 std::cerr << "resolvAttr: funcDecl is "; … … 1418 1418 const SymTab::Indexer & indexer = finder.get_indexer(); 1419 1419 AltList & alternatives = finder.get_alternatives(); 1420 if ( typesCompatibleIgnoreQualifiers( argType, function-> get_parameters().front()->get_type(), indexer, env ) ) {1420 if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) { 1421 1421 Cost cost = Cost::zero; 1422 1422 Expression * newExpr = data.combine( cost ); 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1425 1425 AssertionList{}, Cost::zero, cost } ); 1426 1426 for ( DeclarationWithType * retVal : function->returnVals ) { … … 1431 1431 } 1432 1432 1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) { 1434 1434 // assume no 'pointer-to-attribute' 1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1436 1436 assert( nameExpr ); 1437 1437 std::list< SymTab::Indexer::IdData > attrList; … … 1439 1439 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1440 1440 for ( auto & data : attrList ) { 1441 DeclarationWithType * id = data.id;1441 const DeclarationWithType * id = data.id; 1442 1442 // check if the type is function 1443 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {1443 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) { 1444 1444 // assume exactly one parameter 1445 if ( function-> get_parameters().size() == 1 ) {1445 if ( function->parameters.size() == 1 ) { 1446 1446 if ( attrExpr->get_isType() ) { 1447 1447 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); … … 1462 1462 Cost cost = Cost::zero; 1463 1463 Expression * newExpr = data.combine( cost ); 1464 alternatives.push_back( Alternative{ 1464 alternatives.push_back( Alternative{ 1465 1465 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1466 1466 renameTypes( alternatives.back().expr ); … … 1469 1469 } 1470 1470 1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) { 1472 1472 AlternativeFinder firstFinder( indexer, env ); 1473 1473 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1486 1486 cloneAll( second.need, need ); 1487 1487 1488 LogicalExpr *newExpr = new LogicalExpr{ 1488 LogicalExpr *newExpr = new LogicalExpr{ 1489 1489 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1492 1492 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1493 1493 } … … 1522 1522 cloneAll( third.need, need ); 1523 1523 AssertionSet have; 1524 1524 1525 1525 // unify true and false types, then infer parameters to produce new alternatives 1526 1526 Type* commonType = nullptr; 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1528 1528 need, have, openVars, indexer, commonType ) ) { 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1530 1530 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1531 1531 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1532 1532 // convert both options to the conditional result type 1533 1533 Cost cost = first.cost + second.cost + third.cost; 1534 cost += computeExpressionConversionCost( 1534 cost += computeExpressionConversionCost( 1535 1535 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1536 cost += computeExpressionConversionCost( 1536 cost += computeExpressionConversionCost( 1537 1537 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1538 1538 // output alternative 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1541 1541 AssertionList( need.begin(), need.end() ), cost }; 1542 1542 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1553 1553 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1554 1554 for ( const Alternative & alt : secondFinder.alternatives ) { 1555 alternatives.push_back( Alternative{ 1555 alternatives.push_back( Alternative{ 1556 1556 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1557 1557 } // for … … 1579 1579 1580 1580 Type* commonType = nullptr; 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1582 1582 openVars, indexer, commonType ) ) { 1583 RangeExpr * newExpr = 1583 RangeExpr * newExpr = 1584 1584 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1585 1585 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1588 1588 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1589 1589 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1612 1612 cloneAll( alt.need, need ); 1613 1613 } 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1617 1617 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1618 1618 } // for … … 1633 1633 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1634 1634 for ( Alternative & alt : finder.alternatives ) { 1635 alternatives.push_back( Alternative{ 1635 alternatives.push_back( Alternative{ 1636 1636 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1637 1637 } … … 1685 1685 cloneAll( alt.need, need ); 1686 1686 AssertionSet have; 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1689 1689 // those are open vars? 1690 1690 PRINT( 1691 1691 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1692 1692 ) 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1697 1697 // types to cast to. 1698 1698 int discardedValues = alt.expr->result->size() - toType->size(); 1699 1699 if ( discardedValues < 0 ) continue; 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1702 1702 // atomic type (e.g. (int)([1, 2, 3])) 1703 1703 1704 1704 // unification run for side-effects 1705 1705 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); … … 1710 1710 // count one safe conversion for each value that is thrown away 1711 1711 thisCost.incSafe( discardedValues ); 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1716 1716 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1717 1717 inferParameters( newAlt, back_inserter( candidates ) ); -
src/ResolvExpr/CastCost.cc
r1f1c102 rf53acdf8 37 37 struct CastCost_old : public ConversionCost { 38 38 public: 39 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );39 CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 40 40 41 41 using ConversionCost::previsit; 42 42 using ConversionCost::postvisit; 43 void postvisit( BasicType * basicType );44 void postvisit( PointerType * pointerType );43 void postvisit( const BasicType * basicType ); 44 void postvisit( const PointerType * pointerType ); 45 45 }; 46 46 47 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {48 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {49 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name()) ) {47 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 48 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 49 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 50 50 if ( eqvClass->type ) { 51 51 return castCost( src, eqvClass->type, indexer, env ); … … 53 53 return Cost::infinity; 54 54 } 55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name()) ) {55 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 56 56 // all typedefs should be gone by this point 57 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );57 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 58 58 if ( type->base ) { 59 59 return castCost( src, type->base, indexer, env ) + Cost::safe; … … 74 74 PRINT( std::cerr << "compatible!" << std::endl; ) 75 75 return Cost::zero; 76 } else if ( dynamic_cast< VoidType* >( dest ) ) {76 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 77 77 return Cost::safe; 78 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {78 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 79 79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 80 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {80 return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 81 81 return ptrsCastable( t1, t2, env, indexer ); 82 82 }); 83 83 } else { 84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment & ))84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & )) 87 87 castCost ); 88 88 src->accept( converter ); … … 96 96 } 97 97 98 CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )98 CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 99 99 : ConversionCost( dest, indexer, env, costFunc ) { 100 100 } 101 101 102 void CastCost_old::postvisit( BasicType *basicType ) {103 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );102 void CastCost_old::postvisit( const BasicType * basicType ) { 103 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest ); 104 104 if ( destAsPointer && basicType->isInteger() ) { 105 // necessary for, e.g. unsigned long => void *105 // necessary for, e.g. unsigned long => void * 106 106 cost = Cost::unsafe; 107 107 } else { … … 110 110 } 111 111 112 void CastCost_old::postvisit( PointerType *pointerType ) {113 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {114 if ( pointerType-> get_qualifiers() <= destAsPtr->get_qualifiers()&& typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {112 void CastCost_old::postvisit( const PointerType * pointerType ) { 113 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 114 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 115 115 cost = Cost::safe; 116 116 } else { … … 125 125 } // if 126 126 } // if 127 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {127 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 128 128 if ( destAsBasic->isInteger() ) { 129 // necessary for, e.g. void * => unsigned long129 // necessary for, e.g. void * => unsigned long 130 130 cost = Cost::unsafe; 131 131 } // if … … 138 138 using ConversionCost_new::postvisit; 139 139 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 142 142 const ast::TypeEnvironment & env, CostCalculation costFunc ) 143 143 : ConversionCost_new( dst, symtab, env, costFunc ) {} … … 182 182 } // anonymous namespace 183 183 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 187 187 ) { 188 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 220 220 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 221 221 #warning cast on ptrsCastable artifact of having two functions, remove when port done 222 return convertToReferenceCost( 223 src, refType, symtab, env, 224 ( int (*)( 225 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 222 return convertToReferenceCost( 223 src, refType, symtab, env, 224 ( int (*)( 225 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 226 226 const ast::TypeEnvironment & ) 227 227 ) ptrsCastable ); … … 229 229 #warning cast on castCost artifact of having two functions, remove when port done 230 230 ast::Pass< CastCost_new > converter{ 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 234 234 const ast::TypeEnvironment & ) 235 235 ) castCost }; -
src/ResolvExpr/CommonType.cc
r1f1c102 rf53acdf8 38 38 namespace ResolvExpr { 39 39 struct CommonType_old : public WithShortCircuiting { 40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );41 Type * get_result() const { return result; }40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 41 Type * get_result() const { return result; } 42 42 43 43 void previsit( BaseSyntaxNode * ) { visit_children = false; } … … 60 60 61 61 private: 62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer );63 template< typename RefType > void handleRefType( RefType * inst, Type *other );64 65 Type * result;66 Type * type2; // inherited62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ); 63 template< typename RefType > void handleRefType( RefType * inst, Type * other ); 64 65 Type * result; 66 Type * type2; // inherited 67 67 bool widenFirst, widenSecond; 68 68 const SymTab::Indexer &indexer; … … 80 80 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 81 81 ) 82 if ( (widenFirst || t2-> get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {82 if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) { 83 83 PRINT( 84 84 std::cerr << "widen okay" << std::endl; 85 85 ) 86 common-> get_qualifiers() |= t1->get_qualifiers();87 common-> get_qualifiers() |= t2->get_qualifiers();86 common->tq |= t1->tq; 87 common->tq |= t2->tq; 88 88 return common; 89 89 } … … 95 95 } 96 96 97 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {97 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 98 98 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 99 99 … … 127 127 std::cerr << "formal is reference; result should be reference" << std::endl; 128 128 ) 129 result = new ReferenceType( ref1-> get_qualifiers(), result );129 result = new ReferenceType( ref1->tq, result ); 130 130 } 131 131 PRINT( … … 138 138 139 139 type1->accept( visitor ); 140 Type * result = visitor.pass.get_result();140 Type * result = visitor.pass.get_result(); 141 141 if ( ! result ) { 142 142 // this appears to be handling for opaque type declarations 143 143 if ( widenSecond ) { 144 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {145 if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {146 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );144 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) { 145 if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) { 146 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 147 147 if ( type->get_base() ) { 148 Type::Qualifiers tq1 = type1-> get_qualifiers(), tq2 = type2->get_qualifiers();148 Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq; 149 149 AssertionSet have, need; 150 150 OpenVarSet newOpen( openVars ); 151 type1-> get_qualifiers()= Type::Qualifiers();152 type->get_base()-> get_qualifiers()= tq1;151 type1->tq = Type::Qualifiers(); 152 type->get_base()->tq = tq1; 153 153 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) { 154 154 result = type1->clone(); 155 result-> get_qualifiers()= tq1 | tq2;155 result->tq = tq1 | tq2; 156 156 } // if 157 type1-> get_qualifiers()= tq1;158 type->get_base()-> get_qualifiers()= Type::Qualifiers();157 type1->tq = tq1; 158 type->get_base()->tq = Type::Qualifiers(); 159 159 } // if 160 160 } // if … … 190 190 */ 191 191 { 192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 193 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 198 198 }, 199 199 { 200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 201 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 206 206 }, 207 207 { 208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 209 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 214 214 }, 215 215 { 216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 217 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 222 222 }, 223 223 { 224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt,224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt, 225 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 230 230 }, 231 231 { 232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt,232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, 233 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 238 238 }, 239 239 { 240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt,240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, 241 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 246 246 }, 247 247 { 248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt,248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, 249 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 254 254 }, 255 255 { 256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt,256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, 257 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 262 262 }, 263 263 { 264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt,264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, 265 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 270 270 }, 271 271 { 272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt,272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, 273 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 278 278 }, 279 279 { 280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 281 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 286 286 }, 287 287 { 288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128,288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 289 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 294 294 }, 295 295 { 296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128,296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 297 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 302 302 }, 303 303 { 304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16,304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 305 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 310 310 }, 311 311 { 312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex,312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 313 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, … … 318 318 }, 319 319 { 320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32,320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 321 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, … … 326 326 }, 327 327 { 328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 329 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, … … 334 334 }, 335 335 { 336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float,336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 337 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, … … 342 342 }, 343 343 { 344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 345 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, … … 350 350 }, 351 351 { 352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x,352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 353 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, … … 358 358 }, 359 359 { 360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 361 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, … … 366 366 }, 367 367 { 368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64,368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 369 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, … … 374 374 }, 375 375 { 376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 377 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, … … 382 382 }, 383 383 { 384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double,384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 385 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, … … 390 390 }, 391 391 { 392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 393 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, … … 398 398 }, 399 399 { 400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x,400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 401 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, … … 406 406 }, 407 407 { 408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 409 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, … … 422 422 }, 423 423 { 424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128,424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 425 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, … … 430 430 }, 431 431 { 432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 433 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, … … 438 438 }, 439 439 { 440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128,440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 441 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, … … 446 446 }, 447 447 { 448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble,448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 449 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, … … 454 454 }, 455 455 { 456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 457 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, … … 462 462 }, 463 463 { 464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x,464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 465 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, … … 470 470 }, 471 471 { 472 /* _FLDXC*/ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,472 /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 473 473 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 474 474 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, … … 481 481 // GENERATED END 482 482 static_assert( 483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 484 484 "Each basic type kind should have a corresponding row in the combined type matrix" 485 485 ); 486 486 487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) 488 488 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) { 489 489 } … … 491 491 void CommonType_old::postvisit( VoidType * ) {} 492 492 493 void CommonType_old::postvisit( BasicType * basicType ) {494 if ( BasicType * otherBasic = dynamic_cast< BasicType* >( type2 ) ) {493 void CommonType_old::postvisit( BasicType * basicType ) { 494 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) { 495 495 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ]; 496 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers()) || widenSecond ) ) {497 result = new BasicType( basicType-> get_qualifiers() | otherBasic->get_qualifiers(), newType );496 if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) { 497 result = new BasicType( basicType->tq | otherBasic->tq, newType ); 498 498 } // if 499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 500 500 // use signed int in lieu of the enum/zero/one type 501 501 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; 502 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers()) || widenSecond ) ) {503 result = new BasicType( basicType-> get_qualifiers() | type2->get_qualifiers(), newType );502 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) { 503 result = new BasicType( basicType->tq | type2->tq, newType ); 504 504 } // if 505 505 } // if … … 507 507 508 508 template< typename Pointer > 509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer ) {510 if ( TypeInstType * var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) { 510 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) { 511 511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); 512 512 if ( entry != openVars.end() ) { … … 517 517 } 518 518 result = voidPointer->clone(); 519 result-> get_qualifiers() |= otherPointer->get_qualifiers();520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) {523 if ( PointerType * otherPointer = dynamic_cast< PointerType* >( type2 ) ) {519 result->tq |= otherPointer->tq; 520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) { 523 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) { 524 524 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; 525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) { 526 526 getCommonWithVoidPointer( otherPointer, pointerType ); 527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) { 528 528 getCommonWithVoidPointer( pointerType, otherPointer ); 529 } else if ( ( pointerType->get_base()-> get_qualifiers() >= otherPointer->get_base()->get_qualifiers()|| widenFirst )530 && ( pointerType->get_base()-> get_qualifiers() <= otherPointer->get_base()->get_qualifiers()|| widenSecond ) ) {529 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst ) 530 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) { 531 531 // std::cerr << "middle case" << std::endl; 532 Type::Qualifiers tq1 = pointerType->get_base()-> get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();533 pointerType->get_base()-> get_qualifiers()= Type::Qualifiers();534 otherPointer->get_base()-> get_qualifiers()= Type::Qualifiers();532 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq; 533 pointerType->get_base()->tq = Type::Qualifiers(); 534 otherPointer->get_base()->tq = Type::Qualifiers(); 535 535 AssertionSet have, need; 536 536 OpenVarSet newOpen( openVars ); … … 542 542 result = otherPointer->clone(); 543 543 } // if 544 strict_dynamic_cast<PointerType *>(result)->base->get_qualifiers()= tq1 | tq2;544 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2; 545 545 } else { 546 546 /// std::cerr << "place for ptr-to-type" << std::endl; 547 547 } // if 548 pointerType->get_base()-> get_qualifiers()= tq1;549 otherPointer->get_base()-> get_qualifiers()= tq2;548 pointerType->get_base()->tq = tq1; 549 otherPointer->get_base()->tq = tq2; 550 550 } // if 551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 552 552 result = pointerType->clone(); 553 result-> get_qualifiers() |= type2->get_qualifiers();553 result->tq |= type2->tq; 554 554 } // if 555 555 } … … 557 557 void CommonType_old::postvisit( ArrayType * ) {} 558 558 559 void CommonType_old::postvisit( ReferenceType * refType ) {560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {559 void CommonType_old::postvisit( ReferenceType * refType ) { 560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) { 561 561 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; 562 // std::cerr << ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond) << std::endl;563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {562 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl; 563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) { 564 564 getCommonWithVoidPointer( otherRef, refType ); 565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) { 566 566 getCommonWithVoidPointer( refType, otherRef ); 567 } else if ( ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers()|| widenFirst )568 && ( refType->get_base()-> get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond ) ) {567 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) 568 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) { 569 569 // std::cerr << "middle case" << std::endl; 570 Type::Qualifiers tq1 = refType->get_base()-> get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();571 refType->get_base()-> get_qualifiers()= Type::Qualifiers();572 otherRef->get_base()-> get_qualifiers()= Type::Qualifiers();570 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq; 571 refType->get_base()->tq = Type::Qualifiers(); 572 otherRef->get_base()->tq = Type::Qualifiers(); 573 573 AssertionSet have, need; 574 574 OpenVarSet newOpen( openVars ); … … 579 579 result = otherRef->clone(); 580 580 } // if 581 strict_dynamic_cast<ReferenceType *>(result)->base->get_qualifiers()= tq1 | tq2;581 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2; 582 582 } else { 583 583 /// std::cerr << "place for ptr-to-type" << std::endl; 584 584 } // if 585 refType->get_base()-> get_qualifiers()= tq1;586 otherRef->get_base()-> get_qualifiers()= tq2;585 refType->get_base()->tq = tq1; 586 otherRef->get_base()->tq = tq2; 587 587 } // if 588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 589 589 result = refType->clone(); 590 result-> get_qualifiers() |= type2->get_qualifiers();590 result->tq |= type2->tq; 591 591 } // if 592 592 } … … 596 596 void CommonType_old::postvisit( UnionInstType * ) {} 597 597 598 void CommonType_old::postvisit( EnumInstType * enumInstType ) {599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {598 void CommonType_old::postvisit( EnumInstType * enumInstType ) { 599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 600 600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 601 601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); … … 606 606 } 607 607 608 void CommonType_old::postvisit( TypeInstType * inst ) {608 void CommonType_old::postvisit( TypeInstType * inst ) { 609 609 if ( widenFirst ) { 610 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );610 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ); 611 611 if ( nt ) { 612 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 613 613 if ( type->get_base() ) { 614 Type::Qualifiers tq1 = inst-> get_qualifiers(), tq2 = type2->get_qualifiers();614 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq; 615 615 AssertionSet have, need; 616 616 OpenVarSet newOpen( openVars ); 617 type2-> get_qualifiers()= Type::Qualifiers();618 type->get_base()-> get_qualifiers()= tq1;617 type2->tq = Type::Qualifiers(); 618 type->get_base()->tq = tq1; 619 619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) { 620 620 result = type2->clone(); 621 result-> get_qualifiers()= tq1 | tq2;621 result->tq = tq1 | tq2; 622 622 } // if 623 type2-> get_qualifiers()= tq2;624 type->get_base()-> get_qualifiers()= Type::Qualifiers();623 type2->tq = tq2; 624 type->get_base()->tq = Type::Qualifiers(); 625 625 } // if 626 626 } // if … … 631 631 void CommonType_old::postvisit( VarArgsType * ) {} 632 632 633 void CommonType_old::postvisit( ZeroType * zeroType ) {633 void CommonType_old::postvisit( ZeroType * zeroType ) { 634 634 if ( widenFirst ) { 635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {636 if ( widenSecond || zeroType-> get_qualifiers() <= type2->get_qualifiers()) {635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 636 if ( widenSecond || zeroType->tq <= type2->tq ) { 637 637 result = type2->clone(); 638 result-> get_qualifiers() |= zeroType->get_qualifiers();639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {641 result = new BasicType( zeroType-> get_qualifiers(), BasicType::SignedInt );642 result-> get_qualifiers() |= type2->get_qualifiers();643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) {638 result->tq |= zeroType->tq; 639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) { 641 result = new BasicType( zeroType->tq, BasicType::SignedInt ); 642 result->tq |= type2->tq; 643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) { 648 648 if ( widenFirst ) { 649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {650 if ( widenSecond || oneType-> get_qualifiers() <= type2->get_qualifiers()) {649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 650 if ( widenSecond || oneType->tq <= type2->tq ) { 651 651 result = type2->clone(); 652 result-> get_qualifiers() |= oneType->get_qualifiers();653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {655 result = new BasicType( oneType-> get_qualifiers(), BasicType::SignedInt );656 result-> get_qualifiers() |= type2->get_qualifiers();652 result->tq |= oneType->tq; 653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 655 result = new BasicType( oneType->tq, BasicType::SignedInt ); 656 result->tq |= type2->tq; 657 657 } 658 658 } … … 668 668 ast::ptr< ast::Type > result; 669 669 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 672 672 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 673 673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} … … 681 681 #warning remove casts when `commonTypes` moved to new AST 682 682 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ]; 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 688 688 ) { 689 689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 690 690 } 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 693 693 || dynamic_cast< const ast::ZeroType * >( type2 ) 694 694 || dynamic_cast< const ast::OneType * >( type2 ) … … 696 696 #warning remove casts when `commonTypes` moved to new AST 697 697 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 703 703 ) { 704 704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; … … 715 715 if ( entry != open.end() ) { 716 716 ast::AssertionSet need, have; 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 719 719 ) return; 720 720 } … … 727 727 void postvisit( const ast::PointerType * pointer ) { 728 728 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 733 733 ) { 734 734 getCommonWithVoidPointer( pointer2, pointer ); 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 739 739 ) { 740 740 getCommonWithVoidPointer( pointer, pointer2 ); … … 746 746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers; 747 747 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 749 749 // pointer{,2}->base are unchanged 750 750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; 751 751 reset_qualifiers( t1 ); 752 752 reset_qualifiers( t2 ); 753 753 754 754 ast::AssertionSet have, need; 755 755 ast::OpenVarSet newOpen{ open }; … … 758 758 if ( q1.val != q2.val ) { 759 759 // reset result->base->qualifiers to be union of two base qualifiers 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 762 762 )->base.get_and_mutate()->qualifiers = q1 | q2; 763 763 } … … 775 775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 776 776 if ( 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 778 778 ) { 779 779 getCommonWithVoidPointer( ref2, ref ); 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 782 782 ) { 783 783 getCommonWithVoidPointer( ref, ref2 ); … … 788 788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; 789 789 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 791 791 // ref{,2}->base are unchanged 792 792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; … … 800 800 if ( q1.val != q2.val ) { 801 801 // reset result->base->qualifiers to be union of two base qualifiers 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 804 804 )->base.get_and_mutate()->qualifiers = q1 | q2; 805 805 } … … 819 819 820 820 void postvisit( const ast::EnumInstType * enumInst ) { 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 823 823 || dynamic_cast< const ast::ZeroType * >( type2 ) 824 824 || dynamic_cast< const ast::OneType * >( type2 ) … … 834 834 if ( ! widen.first ) return; 835 835 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 838 838 ) { 839 839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; … … 860 860 void postvisit( const ast::ZeroType * zero ) { 861 861 if ( ! widen.first ) return; 862 if ( 862 if ( 863 863 dynamic_cast< const ast::BasicType * >( type2 ) 864 864 || dynamic_cast< const ast::PointerType * >( type2 ) … … 870 870 } 871 871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 872 result = new ast::BasicType{ 872 result = new ast::BasicType{ 873 873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 874 874 } … … 877 877 void postvisit( const ast::OneType * one ) { 878 878 if ( ! widen.first ) return; 879 if ( 879 if ( 880 880 dynamic_cast< const ast::BasicType * >( type2 ) 881 881 || dynamic_cast< const ast::EnumInstType * >( type2 ) … … 886 886 } 887 887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 888 result = new ast::BasicType{ 888 result = new ast::BasicType{ 889 889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 890 890 } … … 894 894 895 895 namespace { 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 900 900 ) { 901 901 ast::ptr<ast::Type> common; … … 926 926 927 927 ast::ptr< ast::Type > commonType( 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 931 931 ) { 932 932 unsigned depth1 = type1->referenceDepth(); … … 940 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 941 const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >(); 942 942 943 943 if ( depth1 > depth2 ) { 944 944 assert( ref1 ); … … 978 978 ast::OpenVarSet newOpen{ open }; 979 979 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 982 982 // {type1,type->base}->strong_ref >= 1 983 983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 984 984 reset_qualifiers( t1 ); 985 985 reset_qualifiers( t2, q1 ); 986 986 987 987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 988 988 result = t1; -
src/ResolvExpr/ConversionCost.cc
r1f1c102 rf53acdf8 46 46 #endif 47 47 48 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {49 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {48 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 49 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 50 50 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 52 52 if ( eqvClass->type ) { 53 53 return conversionCost( src, eqvClass->type, indexer, env ); … … 55 55 return Cost::infinity; 56 56 } 57 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 58 58 PRINT( std::cerr << " found" << std::endl; ) 59 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );59 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 60 60 // all typedefs should be gone by this point 61 61 assert( type ); … … 77 77 PRINT( std::cerr << "compatible!" << std::endl; ) 78 78 return Cost::zero; 79 } else if ( dynamic_cast< VoidType* >( dest ) ) {79 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 80 80 return Cost::safe; 81 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {81 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 82 82 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 83 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){83 return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 84 84 return ptrsAssignable( t1, t2, env ); 85 85 }); 86 86 } else { 87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)( Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&)) 90 90 conversionCost ); 91 91 src->accept( converter ); … … 98 98 } 99 99 100 Cost convertToReferenceCost( Type * src,Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {100 Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 101 101 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 102 102 if ( diff > 0 ) { 103 103 // TODO: document this 104 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );104 Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 105 105 cost.incReference(); 106 106 return cost; 107 107 } else if ( diff < -1 ) { 108 108 // TODO: document this 109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 110 110 cost.incReference(); 111 111 return cost; 112 112 } else if ( diff == 0 ) { 113 ReferenceType * srcAsRef = dynamic_cast<ReferenceType * >( src );114 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );113 const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src ); 114 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 115 115 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 116 116 PRINT( std::cerr << "converting between references" << std::endl; ) 117 Type::Qualifiers tq1 = srcAsRef->base-> get_qualifiers();118 Type::Qualifiers tq2 = destAsRef->base-> get_qualifiers();117 Type::Qualifiers tq1 = srcAsRef->base->tq; 118 Type::Qualifiers tq2 = destAsRef->base->tq; 119 119 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 120 120 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 137 137 } else { 138 138 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)( Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&)) 142 142 conversionCost ); 143 143 src->accept( converter ); … … 145 145 } // if 146 146 } else { 147 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );147 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 148 148 assert( diff == -1 && destAsRef ); 149 149 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) … … 156 156 ) 157 157 // lvalue-to-reference conversion: cv lvalue T => cv T & 158 if ( src-> get_qualifiers() == destAsRef->base->get_qualifiers()) {158 if ( src->tq == destAsRef->base->tq ) { 159 159 return Cost::reference; // cost needs to be non-zero to add cast 160 } if ( src-> get_qualifiers() < destAsRef->base->get_qualifiers()) {160 } if ( src->tq < destAsRef->base->tq ) { 161 161 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 162 162 } else { … … 178 178 } 179 179 180 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {180 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 181 181 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 182 182 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); … … 185 185 } 186 186 187 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )187 ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 188 188 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 189 189 } … … 193 193 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 194 194 _Bool 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 208 208 __float80 209 _Float128 _Float128 _Complex 209 _Float128 _Float128 _Complex 210 210 __float128 211 long double long double _Complex 212 _Float128x _Float128x _Complex 211 long double long double _Complex 212 _Float128x _Float128x _Complex 213 213 */ 214 214 // GENERATED END … … 218 218 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 219 219 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, },221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, },235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, },236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, },237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, },238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, },239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, },240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, },241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, },242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, },243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, },244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, },245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, },246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, },247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, },220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, 221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, }, 235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, }, 236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, }, 237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, }, 238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, }, 239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, }, 240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, }, 241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, }, 242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, }, 243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, }, 244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, }, 245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, }, 246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, }, 247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, }, 248 248 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, 3, 4, 4, }, 249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, },250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, },251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, },252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, },253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, },254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, },255 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, }, 250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, }, 251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, }, 252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, }, 253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, }, 254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, }, 255 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 256 256 }; // costMatrix 257 257 static const int maxIntCost = 15; 258 258 // GENERATED END 259 259 static_assert( 260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 261 261 "Missing row in the cost matrix" 262 262 ); … … 266 266 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 267 267 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 296 296 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, },298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, },299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, },300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, },301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, },302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, },303 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, }, 298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, }, 299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, }, 300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, }, 301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, }, 302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, }, 303 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 304 304 }; // signMatrix 305 305 // GENERATED END 306 306 static_assert( 307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 308 308 "Missing row in the sign matrix" 309 309 ); 310 310 311 void ConversionCost::postvisit( VoidType * ) {311 void ConversionCost::postvisit( const VoidType * ) { 312 312 cost = Cost::infinity; 313 313 } 314 314 315 void ConversionCost::postvisit( BasicType *basicType) {316 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {317 int tableResult = costMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()];315 void ConversionCost::postvisit(const BasicType * basicType) { 316 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 317 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 318 318 if ( tableResult == -1 ) { 319 319 cost = Cost::unsafe; … … 321 321 cost = Cost::zero; 322 322 cost.incSafe( tableResult ); 323 cost.incSign( signMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()] );324 } // if 325 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {323 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 324 } // if 325 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 326 326 // xxx - not positive this is correct, but appears to allow casting int => enum 327 327 cost = Cost::unsafe; … … 330 330 } 331 331 332 void ConversionCost::postvisit( PointerType * pointerType ) {333 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {332 void ConversionCost::postvisit( const PointerType * pointerType ) { 333 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 334 334 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 335 Type::Qualifiers tq1 = pointerType->base-> get_qualifiers();336 Type::Qualifiers tq2 = destAsPtr->base-> get_qualifiers();335 Type::Qualifiers tq1 = pointerType->base->tq; 336 Type::Qualifiers tq2 = destAsPtr->base->tq; 337 337 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 338 338 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 363 363 } 364 364 365 void ConversionCost::postvisit( ArrayType * ) {}366 367 void ConversionCost::postvisit( ReferenceType * refType ) {365 void ConversionCost::postvisit( const ArrayType * ) {} 366 367 void ConversionCost::postvisit( const ReferenceType * refType ) { 368 368 // Note: dest can never be a reference, since it would have been caught in an earlier check 369 assert( ! dynamic_cast< ReferenceType * >( dest ) );369 assert( ! dynamic_cast< const ReferenceType * >( dest ) ); 370 370 // convert reference to rvalue: cv T1 & => T2 371 371 // recursively compute conversion cost from T1 to T2. 372 372 // cv can be safely dropped because of 'implicit dereference' behavior. 373 373 cost = costFunc( refType->base, dest, indexer, env ); 374 if ( refType->base-> get_qualifiers() == dest->get_qualifiers()) {374 if ( refType->base->tq == dest->tq ) { 375 375 cost.incReference(); // prefer exact qualifiers 376 } else if ( refType->base-> get_qualifiers() < dest->get_qualifiers()) {376 } else if ( refType->base->tq < dest->tq ) { 377 377 cost.incSafe(); // then gaining qualifiers 378 378 } else { … … 382 382 } 383 383 384 void ConversionCost::postvisit( FunctionType * ) {}385 386 void ConversionCost::postvisit( StructInstType * inst ) {387 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {384 void ConversionCost::postvisit( const FunctionType * ) {} 385 386 void ConversionCost::postvisit( const StructInstType * inst ) { 387 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 388 388 if ( inst->name == destAsInst->name ) { 389 389 cost = Cost::zero; … … 392 392 } 393 393 394 void ConversionCost::postvisit( UnionInstType * inst ) {395 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {394 void ConversionCost::postvisit( const UnionInstType * inst ) { 395 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 396 396 if ( inst->name == destAsInst->name ) { 397 397 cost = Cost::zero; … … 400 400 } 401 401 402 void ConversionCost::postvisit( EnumInstType * ) {402 void ConversionCost::postvisit( const EnumInstType * ) { 403 403 static Type::Qualifiers q; 404 404 static BasicType integer( q, BasicType::SignedInt ); … … 409 409 } 410 410 411 void ConversionCost::postvisit( TraitInstType * ) {}412 413 void ConversionCost::postvisit( TypeInstType *inst ) {414 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {411 void ConversionCost::postvisit( const TraitInstType * ) {} 412 413 void ConversionCost::postvisit( const TypeInstType * inst ) { 414 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 415 415 cost = costFunc( eqvClass->type, dest, indexer, env ); 416 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {416 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) { 417 417 if ( inst->name == destAsInst->name ) { 418 418 cost = Cost::zero; 419 419 } 420 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {421 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );420 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) { 421 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 422 422 // all typedefs should be gone by this point 423 423 assert( type ); … … 428 428 } 429 429 430 void ConversionCost::postvisit( TupleType * tupleType ) {430 void ConversionCost::postvisit( const TupleType * tupleType ) { 431 431 Cost c = Cost::zero; 432 if ( TupleType * destAsTuple = dynamic_cast<TupleType * >( dest ) ) {432 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) { 433 433 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 434 434 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 435 435 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 436 Cost newCost = costFunc( * srcIt++, *destIt++, indexer, env );436 Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env ); 437 437 if ( newCost == Cost::infinity ) { 438 438 return; … … 448 448 } 449 449 450 void ConversionCost::postvisit( VarArgsType * ) {451 if ( dynamic_cast< VarArgsType* >( dest ) ) {452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( ZeroType * ) {457 if ( dynamic_cast< ZeroType * >( dest ) ) {458 cost = Cost::zero; 459 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {460 // copied from visit(BasicType *) for signed int, but +1 for safe conversions461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];450 void ConversionCost::postvisit( const VarArgsType * ) { 451 if ( dynamic_cast< const VarArgsType * >( dest ) ) { 452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( const ZeroType * ) { 457 if ( dynamic_cast< const ZeroType * >( dest ) ) { 458 cost = Cost::zero; 459 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 460 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 462 462 if ( tableResult == -1 ) { 463 463 cost = Cost::unsafe; … … 465 465 cost = Cost::zero; 466 466 cost.incSafe( tableResult + 1 ); 467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );468 } // if 469 } else if ( dynamic_cast< PointerType* >( dest ) ) {467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 468 } // if 469 } else if ( dynamic_cast< const PointerType * >( dest ) ) { 470 470 cost = Cost::zero; 471 471 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation … … 473 473 } 474 474 475 void ConversionCost::postvisit( OneType * ) {476 if ( dynamic_cast< OneType * >( dest ) ) {477 cost = Cost::zero; 478 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {479 // copied from visit(BasicType *) for signed int, but +1 for safe conversions480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];475 void ConversionCost::postvisit( const OneType * ) { 476 if ( dynamic_cast< const OneType * >( dest ) ) { 477 cost = Cost::zero; 478 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 479 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 481 481 if ( tableResult == -1 ) { 482 482 cost = Cost::unsafe; … … 484 484 cost = Cost::zero; 485 485 cost.incSafe( tableResult + 1 ); 486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 487 487 } // if 488 488 } // if … … 729 729 auto dstEnd = dstAsTuple->types.end(); 730 730 while ( srcIt != srcEnd && dstIt != dstEnd ) { 731 Cost newCost = costCalc( * srcIt++, *dstIt++, symtab, env );731 Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env ); 732 732 if ( newCost == Cost::infinity ) { 733 733 return; -
src/ResolvExpr/ConversionCost.h
r1f1c102 rf53acdf8 33 33 class TypeEnvironment; 34 34 35 typedef std::function<Cost( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;35 typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 36 36 struct ConversionCost : public WithShortCircuiting { 37 37 public: 38 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );38 ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction ); 39 39 40 40 Cost get_cost() const { return cost; } 41 41 42 void previsit( BaseSyntaxNode * ) { visit_children = false; }42 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 43 43 44 void postvisit( VoidType * voidType );45 void postvisit( BasicType * basicType );46 void postvisit( PointerType * pointerType );47 void postvisit( ArrayType * arrayType );48 void postvisit( ReferenceType * refType );49 void postvisit( FunctionType * functionType );50 void postvisit( StructInstType * aggregateUseType );51 void postvisit( UnionInstType * aggregateUseType );52 void postvisit( EnumInstType * aggregateUseType );53 void postvisit( TraitInstType * aggregateUseType );54 void postvisit( TypeInstType * aggregateUseType );55 void postvisit( TupleType * tupleType );56 void postvisit( VarArgsType * varArgsType );57 void postvisit( ZeroType * zeroType );58 void postvisit( OneType * oneType );44 void postvisit( const VoidType * voidType ); 45 void postvisit( const BasicType * basicType ); 46 void postvisit( const PointerType * pointerType ); 47 void postvisit( const ArrayType * arrayType ); 48 void postvisit( const ReferenceType * refType ); 49 void postvisit( const FunctionType * functionType ); 50 void postvisit( const StructInstType * aggregateUseType ); 51 void postvisit( const UnionInstType * aggregateUseType ); 52 void postvisit( const EnumInstType * aggregateUseType ); 53 void postvisit( const TraitInstType * aggregateUseType ); 54 void postvisit( const TypeInstType * aggregateUseType ); 55 void postvisit( const TupleType * tupleType ); 56 void postvisit( const VarArgsType * varArgsType ); 57 void postvisit( const ZeroType * zeroType ); 58 void postvisit( const OneType * oneType ); 59 59 protected: 60 Type *dest;60 const Type * dest; 61 61 const SymTab::Indexer &indexer; 62 62 Cost cost; … … 65 65 }; 66 66 67 typedef std::function<int( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;68 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );67 typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction; 68 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ); 69 69 70 70 // Some function pointer types, differ in return type. -
src/ResolvExpr/PtrsAssignable.cc
r1f1c102 rf53acdf8 27 27 namespace ResolvExpr { 28 28 struct PtrsAssignable : public WithShortCircuiting { 29 PtrsAssignable( Type *dest, const TypeEnvironment &env );29 PtrsAssignable( const Type * dest, const TypeEnvironment &env ); 30 30 31 31 int get_result() const { return result; } 32 32 33 void previsit( Type * ) { visit_children = false; }34 35 void postvisit( VoidType * voidType );36 void postvisit( BasicType * basicType );37 void postvisit( PointerType * pointerType );38 void postvisit( ArrayType * arrayType );39 void postvisit( FunctionType * functionType );40 void postvisit( StructInstType * inst );41 void postvisit( UnionInstType * inst );42 void postvisit( EnumInstType * inst );43 void postvisit( TraitInstType * inst );44 void postvisit( TypeInstType * inst );45 void postvisit( TupleType * tupleType );46 void postvisit( VarArgsType * varArgsType );47 void postvisit( ZeroType * zeroType );48 void postvisit( OneType * oneType );33 void previsit( const Type * ) { visit_children = false; } 34 35 void postvisit( const VoidType * voidType ); 36 void postvisit( const BasicType * basicType ); 37 void postvisit( const PointerType * pointerType ); 38 void postvisit( const ArrayType * arrayType ); 39 void postvisit( const FunctionType * functionType ); 40 void postvisit( const StructInstType * inst ); 41 void postvisit( const UnionInstType * inst ); 42 void postvisit( const EnumInstType * inst ); 43 void postvisit( const TraitInstType * inst ); 44 void postvisit( const TypeInstType * inst ); 45 void postvisit( const TupleType * tupleType ); 46 void postvisit( const VarArgsType * varArgsType ); 47 void postvisit( const ZeroType * zeroType ); 48 void postvisit( const OneType * oneType ); 49 49 private: 50 Type *dest;50 const Type * dest; 51 51 int result; 52 52 const TypeEnvironment &env; 53 53 }; 54 54 55 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) { 56 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 57 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 59 59 return ptrsAssignable( src, eqvClass->type, env ); 60 60 } // if 61 61 } // if 62 if ( dynamic_cast< VoidType* >( dest ) ) {62 if ( dynamic_cast< const VoidType* >( dest ) ) { 63 63 // void * = T * for any T is unsafe 64 64 // xxx - this should be safe, but that currently breaks the build … … 71 71 } 72 72 73 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}74 75 void PtrsAssignable::postvisit( VoidType * ) {73 PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( const VoidType * ) { 76 76 // T * = void * is disallowed - this is a change from C, where any 77 77 // void * can be assigned or passed to a non-void pointer without a cast. 78 78 } 79 79 80 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType) {}82 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType) {}83 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType) {}84 85 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst) {}86 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst) {}87 88 void PtrsAssignable::postvisit( EnumInstType * ) {89 if ( dynamic_cast< BasicType* >( dest ) ) {80 void PtrsAssignable::postvisit( const BasicType * ) {} 81 void PtrsAssignable::postvisit( const PointerType * ) {} 82 void PtrsAssignable::postvisit( const ArrayType * ) {} 83 void PtrsAssignable::postvisit( const FunctionType * ) {} 84 85 void PtrsAssignable::postvisit( const StructInstType * ) {} 86 void PtrsAssignable::postvisit( const UnionInstType * ) {} 87 88 void PtrsAssignable::postvisit( const EnumInstType * ) { 89 if ( dynamic_cast< const BasicType* >( dest ) ) { 90 90 // int * = E *, etc. is safe. This isn't technically correct, as each 91 91 // enum has one basic type that it is compatible with, an that type can … … 97 97 } 98 98 99 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst) {}100 void PtrsAssignable::postvisit( TypeInstType *inst ) {101 if ( const EqvClass * eqvClass = env.lookup( inst->get_name()) ) {99 void PtrsAssignable::postvisit( const TraitInstType * ) {} 100 void PtrsAssignable::postvisit( const TypeInstType * inst ) { 101 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 102 102 if ( eqvClass->type ) { 103 103 // T * = S * for any S depends on the type bound to T … … 107 107 } 108 108 109 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType) {}110 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType) {}111 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType) {}112 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType) {}109 void PtrsAssignable::postvisit( const TupleType * ) {} 110 void PtrsAssignable::postvisit( const VarArgsType * ) {} 111 void PtrsAssignable::postvisit( const ZeroType * ) {} 112 void PtrsAssignable::postvisit( const OneType * ) {} 113 113 114 114 // TODO: Get rid of the `_new` suffix when the old version is removed. -
src/ResolvExpr/PtrsCastable.cc
r1f1c102 rf53acdf8 29 29 struct PtrsCastable_old : public WithShortCircuiting { 30 30 public: 31 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );31 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 32 32 33 33 int get_result() const { return result; } 34 34 35 void previsit( Type * ) { visit_children = false; }36 37 void postvisit( VoidType * voidType );38 void postvisit( BasicType * basicType );39 void postvisit( PointerType * pointerType );40 void postvisit( ArrayType * arrayType );41 void postvisit( FunctionType * functionType );42 void postvisit( StructInstType * inst );43 void postvisit( UnionInstType * inst );44 void postvisit( EnumInstType * inst );45 void postvisit( TraitInstType * inst );46 void postvisit( TypeInstType * inst );47 void postvisit( TupleType * tupleType );48 void postvisit( VarArgsType * varArgsType );49 void postvisit( ZeroType * zeroType );50 void postvisit( OneType * oneType );35 void previsit( const Type * ) { visit_children = false; } 36 37 void postvisit( const VoidType * voidType ); 38 void postvisit( const BasicType * basicType ); 39 void postvisit( const PointerType * pointerType ); 40 void postvisit( const ArrayType * arrayType ); 41 void postvisit( const FunctionType * functionType ); 42 void postvisit( const StructInstType * inst ); 43 void postvisit( const UnionInstType * inst ); 44 void postvisit( const EnumInstType * inst ); 45 void postvisit( const TraitInstType * inst ); 46 void postvisit( const TypeInstType * inst ); 47 void postvisit( const TupleType * tupleType ); 48 void postvisit( const VarArgsType * varArgsType ); 49 void postvisit( const ZeroType * zeroType ); 50 void postvisit( const OneType * oneType ); 51 51 private: 52 Type *dest;52 const Type * dest; 53 53 int result; 54 54 const TypeEnvironment &env; … … 57 57 58 58 namespace { 59 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {60 if ( dynamic_cast< FunctionType* >( src ) ) {59 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 60 if ( dynamic_cast< const FunctionType* >( src ) ) { 61 61 return -1; 62 } else if ( TypeInstType *typeInst = dynamic_cast<TypeInstType* >( src ) ) {63 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name()) ) {64 if ( TypeDecl *tyDecl = dynamic_cast<TypeDecl* >( ntDecl ) ) {65 if ( tyDecl-> get_kind()== TypeDecl::Ftype ) {62 } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) { 63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) { 64 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) { 65 if ( tyDecl->kind == TypeDecl::Ftype ) { 66 66 return -1; 67 67 } // if 68 68 } //if 69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 70 70 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 71 71 return -1; … … 75 75 return 1; 76 76 } 77 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {77 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 78 78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast 79 79 } 80 80 } 81 81 82 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {83 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {82 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 85 85 // xxx - should this be ptrsCastable? 86 86 return ptrsAssignable( src, eqvClass->type, env ); 87 87 } // if 88 88 } // if 89 if ( dynamic_cast< VoidType* >( dest ) ) {89 if ( dynamic_cast< const VoidType* >( dest ) ) { 90 90 return objectCast( src, env, indexer ); 91 91 } else { … … 96 96 } 97 97 98 PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )98 PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) 99 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 100 100 } 101 101 102 void PtrsCastable_old::postvisit( VoidType * ) {103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( BasicType * ) {107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( PointerType * ) {111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( ArrayType * ) {115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( FunctionType * ) {102 void PtrsCastable_old::postvisit( const VoidType * ) { 103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( const BasicType * ) { 107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( const PointerType * ) { 111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( const ArrayType * ) { 115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( const FunctionType * ) { 119 119 // result = -1; 120 120 result = functionCast( dest, env, indexer ); 121 121 } 122 122 123 void PtrsCastable_old::postvisit( StructInstType * ) {124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( UnionInstType * ) {128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( EnumInstType * ) {132 if ( dynamic_cast< EnumInstType* >( dest ) ) {123 void PtrsCastable_old::postvisit( const StructInstType * ) { 124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( const UnionInstType * ) { 128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( const EnumInstType * ) { 132 if ( dynamic_cast< const EnumInstType * >( dest ) ) { 133 133 result = 1; 134 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {135 if ( bt-> get_kind()== BasicType::SignedInt ) {134 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) { 135 if ( bt->kind == BasicType::SignedInt ) { 136 136 result = 0; 137 137 } else { … … 143 143 } 144 144 145 void PtrsCastable_old::postvisit( TraitInstType * ) {}146 147 void PtrsCastable_old::postvisit( TypeInstType *inst ) {145 void PtrsCastable_old::postvisit( const TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit( const TypeInstType *inst ) { 148 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 149 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 150 150 } 151 151 152 void PtrsCastable_old::postvisit( TupleType * ) {153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( VarArgsType * ) {157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( ZeroType * ) {161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( OneType * ) {152 void PtrsCastable_old::postvisit( const TupleType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( const VarArgsType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( const ZeroType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( const OneType * ) { 165 165 result = objectCast( dest, env, indexer ); 166 166 } … … 168 168 namespace { 169 169 // can this type be cast to an object (1 for yes, -1 for no) 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 172 172 ) { 173 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { … … 191 191 192 192 // can this type be cast to a function (inverse of objectCast) 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 195 195 ) { 196 196 return -1 * objectCast( src, env, symtab ); … … 204 204 int result; 205 205 206 PtrsCastable_new( 206 PtrsCastable_new( 207 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} … … 278 278 } // anonymous namespace 279 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 283 ) { 284 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { -
src/ResolvExpr/ResolveAssertions.cc
r1f1c102 rf53acdf8 9 9 // Author : Aaron B. Moss 10 10 // Created On : Fri Oct 05 13:46:00 2018 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Fri Oct 05 13:46:00 201813 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 16:10:37 2019 13 // Update Count : 2 14 14 // 15 15 … … 197 197 } 198 198 if ( i == b.size() /* && i < a.size() */ ) return 1; 199 199 200 200 int c = a[i].compare( b[i] ); 201 201 if ( c != 0 ) return c; … … 220 220 221 221 /// Initial resolution state for an alternative 222 ResnState( Alternative & a, SymTab::Indexer& indexer )222 ResnState( Alternative & a, SymTab::Indexer & indexer ) 223 223 : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) { 224 224 need.swap( a.need ); … … 226 226 227 227 /// Updated resolution state with new need-list 228 ResnState( ResnState && o, IterateFlag )228 ResnState( ResnState && o, IterateFlag ) 229 229 : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(), 230 230 inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) { … … 234 234 235 235 /// Binds a single assertion, updating resolution state 236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative& alt,237 AssnCandidate & match, InferCache& inferred ) {238 239 DeclarationWithType* candidate = match.cdata.id;240 assertf( candidate-> get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost );236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt, 237 AssnCandidate & match, InferCache & inferred ) { 238 239 const DeclarationWithType * candidate = match.cdata.id; 240 assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost ); 243 243 delete varExpr->result; 244 244 varExpr->result = match.adjType->clone(); … … 247 247 // place newly-inferred assertion in proper place in cache 248 248 inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{ 249 candidate-> get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),249 candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(), 250 250 varExpr }; 251 251 } 252 252 253 253 /// Adds a captured assertion to the symbol table 254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer &indexer ) {254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) { 255 255 for ( auto& i : assertSet ) { 256 256 if ( i.second.isUsed ) { … … 264 264 265 265 /// Resolve a single assertion, in context 266 bool resolveAssertion( AssertionItem & assn, ResnState& resn ) {266 bool resolveAssertion( AssertionItem & assn, ResnState & resn ) { 267 267 // skip unused assertions 268 268 if ( ! assn.info.isUsed ) return true; … … 274 274 // find the candidates that unify with the desired type 275 275 CandidateList matches; 276 for ( const auto & cdata : candidates ) {277 DeclarationWithType* candidate = cdata.id;276 for ( const auto & cdata : candidates ) { 277 const DeclarationWithType * candidate = cdata.id; 278 278 279 279 // build independent unification context for candidate … … 281 281 TypeEnvironment newEnv{ resn.alt.env }; 282 282 OpenVarSet newOpenVars{ resn.alt.openVars }; 283 Type * adjType = candidate->get_type()->clone();283 Type * adjType = candidate->get_type()->clone(); 284 284 adjustExprType( adjType, newEnv, resn.indexer ); 285 285 renameTyVars( adjType ); … … 368 368 std::string resKey = SymTab::Mangler::mangleType( resType ); 369 369 delete resType; 370 return std::move( resKey );371 } 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 370 return resKey; 371 } 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 374 374 /// threshold. 375 375 void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) { … … 406 406 ResnList resns{ ResnState{ alt, root_indexer } }; 407 407 ResnList new_resns{}; 408 408 409 409 // Pruning thresholds by result type of the output alternatives. 410 410 // Alternatives *should* be generated in sorted order, so no need to retroactively prune -
src/ResolvExpr/Resolver.cc
r1f1c102 rf53acdf8 562 562 // TODO: Replace *exception type with &exception type. 563 563 if ( throwStmt->get_expr() ) { 564 StructDecl * exception_decl = 565 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 564 const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 566 565 assert( exception_decl ); 567 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl) );566 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) ); 568 567 findSingleExpression( throwStmt->expr, exceptType, indexer ); 569 568 } … … 972 971 /// Calls the CandidateFinder and finds the single best candidate 973 972 CandidateRef findUnfinishedKindExpression( 974 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 973 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 975 974 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 976 975 ) { … … 994 993 // produce invalid error if no candidates 995 994 if ( candidates.empty() ) { 996 SemanticError( untyped, 997 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 995 SemanticError( untyped, 996 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 998 997 "expression: ") ); 999 998 } … … 1031 1030 if ( winners.size() != 1 ) { 1032 1031 std::ostringstream stream; 1033 stream << "Cannot choose between " << winners.size() << " alternatives for " 1032 stream << "Cannot choose between " << winners.size() << " alternatives for " 1034 1033 << kind << (kind != "" ? " " : "") << "expression\n"; 1035 1034 ast::print( stream, untyped ); … … 1054 1053 struct StripCasts_new final { 1055 1054 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1056 if ( 1057 castExpr->isGenerated 1058 && typesCompatible( castExpr->arg->result, castExpr->result ) 1055 if ( 1056 castExpr->isGenerated 1057 && typesCompatible( castExpr->arg->result, castExpr->result ) 1059 1058 ) { 1060 1059 // generated cast is the same type as its argument, remove it after keeping env 1061 return ast::mutate_field( 1060 return ast::mutate_field( 1062 1061 castExpr->arg.get(), &ast::Expr::env, castExpr->env ); 1063 1062 } … … 1088 1087 1089 1088 /// Establish post-resolver invariants for expressions 1090 void finishExpr( 1091 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1089 void finishExpr( 1090 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1092 1091 const ast::TypeSubstitution * oldenv = nullptr 1093 1092 ) { 1094 1093 // set up new type substitution for expression 1095 ast::ptr< ast::TypeSubstitution > newenv = 1094 ast::ptr< ast::TypeSubstitution > newenv = 1096 1095 oldenv ? oldenv : new ast::TypeSubstitution{}; 1097 1096 env.writeToSubstitution( *newenv.get_and_mutate() ); … … 1102 1101 } // anonymous namespace 1103 1102 1104 1103 1105 1104 ast::ptr< ast::Expr > resolveInVoidContext( 1106 1105 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1107 1106 ) { 1108 1107 assertf( expr, "expected a non-null expression" ); 1109 1108 1110 1109 // set up and resolve expression cast to void 1111 1110 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1112 CandidateRef choice = findUnfinishedKindExpression( 1111 CandidateRef choice = findUnfinishedKindExpression( 1113 1112 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1114 1113 1115 1114 // a cast expression has either 0 or 1 interpretations (by language rules); 1116 1115 // if 0, an exception has already been thrown, and this code will not run … … 1122 1121 1123 1122 namespace { 1124 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1123 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1125 1124 /// context. 1126 ast::ptr< ast::Expr > findVoidExpression( 1125 ast::ptr< ast::Expr > findVoidExpression( 1127 1126 const ast::Expr * untyped, const ast::SymbolTable & symtab 1128 1127 ) { … … 1134 1133 } 1135 1134 1136 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1135 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1137 1136 /// lowest cost, returning the resolved version 1138 1137 ast::ptr< ast::Expr > findKindExpression( 1139 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1140 std::function<bool(const Candidate &)> pred = anyCandidate, 1138 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1139 std::function<bool(const Candidate &)> pred = anyCandidate, 1141 1140 const std::string & kind = "", ResolvMode mode = {} 1142 1141 ) { 1143 1142 if ( ! untyped ) return {}; 1144 CandidateRef choice = 1143 CandidateRef choice = 1145 1144 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1146 1145 finishExpr( choice->expr, choice->env, untyped->env ); … … 1149 1148 1150 1149 /// Resolve `untyped` to the single expression whose candidate is the best match 1151 ast::ptr< ast::Expr > findSingleExpression( 1152 const ast::Expr * untyped, const ast::SymbolTable & symtab 1150 ast::ptr< ast::Expr > findSingleExpression( 1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1153 1152 ) { 1154 1153 return findKindExpression( untyped, symtab ); … … 1170 1169 bool hasIntegralType( const Candidate & i ) { 1171 1170 const ast::Type * type = i.expr->result; 1172 1171 1173 1172 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1174 1173 return bt->isInteger(); 1175 } else if ( 1176 dynamic_cast< const ast::EnumInstType * >( type ) 1174 } else if ( 1175 dynamic_cast< const ast::EnumInstType * >( type ) 1177 1176 || dynamic_cast< const ast::ZeroType * >( type ) 1178 1177 || dynamic_cast< const ast::OneType * >( type ) … … 1183 1182 1184 1183 /// Resolve `untyped` as an integral expression, returning the resolved version 1185 ast::ptr< ast::Expr > findIntegralExpression( 1186 const ast::Expr * untyped, const ast::SymbolTable & symtab 1184 ast::ptr< ast::Expr > findIntegralExpression( 1185 const ast::Expr * untyped, const ast::SymbolTable & symtab 1187 1186 ) { 1188 1187 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); … … 1192 1191 bool isCharType( const ast::Type * t ) { 1193 1192 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1194 return bt->kind == ast::BasicType::Char 1195 || bt->kind == ast::BasicType::SignedChar 1193 return bt->kind == ast::BasicType::Char 1194 || bt->kind == ast::BasicType::SignedChar 1196 1195 || bt->kind == ast::BasicType::UnsignedChar; 1197 1196 } … … 1253 1252 } 1254 1253 1255 ast::ptr< ast::Init > resolveCtorInit( 1256 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1254 ast::ptr< ast::Init > resolveCtorInit( 1255 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1257 1256 ) { 1258 1257 assert( ctorInit ); … … 1261 1260 } 1262 1261 1263 ast::ptr< ast::Expr > resolveStmtExpr( 1264 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1262 ast::ptr< ast::Expr > resolveStmtExpr( 1263 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1265 1264 ) { 1266 1265 assert( stmtExpr ); … … 1303 1302 1304 1303 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1305 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1306 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1307 // twice. The second analysis changes `initContext` because a function type can contain 1308 // object declarations in the return and parameter types. Therefore each value of 1309 // `initContext` is retained so the type on the first analysis is preserved and used for 1304 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1305 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1306 // twice. The second analysis changes `initContext` because a function type can contain 1307 // object declarations in the return and parameter types. Therefore each value of 1308 // `initContext` is retained so the type on the first analysis is preserved and used for 1310 1309 // selecting the RHS. 1311 1310 GuardValue( currentObject ); 1312 1311 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1313 1312 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1314 // enumerator initializers should not use the enum type to initialize, since the 1313 // enumerator initializers should not use the enum type to initialize, since the 1315 1314 // enum type is still incomplete at this point. Use `int` instead. 1316 currentObject = ast::CurrentObject{ 1315 currentObject = ast::CurrentObject{ 1317 1316 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1318 1317 } … … 1325 1324 } 1326 1325 1327 const ast::StaticAssertDecl * Resolver_new::previsit( 1328 const ast::StaticAssertDecl * assertDecl 1326 const ast::StaticAssertDecl * Resolver_new::previsit( 1327 const ast::StaticAssertDecl * assertDecl 1329 1328 ) { 1330 return ast::mutate_field( 1331 assertDecl, &ast::StaticAssertDecl::cond, 1329 return ast::mutate_field( 1330 assertDecl, &ast::StaticAssertDecl::cond, 1332 1331 findIntegralExpression( assertDecl->cond, symtab ) ); 1333 1332 } … … 1338 1337 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1339 1338 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1340 ast::mutate_field( 1341 type, &PtrType::dimension, 1339 ast::mutate_field( 1340 type, &PtrType::dimension, 1342 1341 findSingleExpression( type->dimension, sizeType, symtab ) ); 1343 1342 } … … 1356 1355 visit_children = false; 1357 1356 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" ); 1358 1359 return ast::mutate_field( 1357 1358 return ast::mutate_field( 1360 1359 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1361 1360 } … … 1364 1363 visit_children = false; 1365 1364 1366 asmExpr = ast::mutate_field( 1365 asmExpr = ast::mutate_field( 1367 1366 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1368 1367 1369 1368 if ( asmExpr->inout ) { 1370 1369 asmExpr = ast::mutate_field( 1371 1370 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) ); 1372 1371 } 1373 1372 1374 1373 return asmExpr; 1375 1374 } … … 1388 1387 1389 1388 const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1390 return ast::mutate_field( 1389 return ast::mutate_field( 1391 1390 whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) ); 1392 1391 } … … 1409 1408 GuardValue( currentObject ); 1410 1409 switchStmt = ast::mutate_field( 1411 switchStmt, &ast::SwitchStmt::cond, 1410 switchStmt, &ast::SwitchStmt::cond, 1412 1411 findIntegralExpression( switchStmt->cond, symtab ) ); 1413 1412 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; … … 1420 1419 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1421 1420 "expression." ); 1422 1423 ast::ptr< ast::Expr > untyped = 1421 1422 ast::ptr< ast::Expr > untyped = 1424 1423 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1425 1424 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab ); 1426 1427 // case condition cannot have a cast in C, so it must be removed here, regardless of 1425 1426 // case condition cannot have a cast in C, so it must be removed here, regardless of 1428 1427 // whether it would perform a conversion. 1429 1428 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1430 1429 swap_and_save_env( newExpr, castExpr->arg ); 1431 1430 } 1432 1431 1433 1432 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1434 1433 } … … 1443 1442 ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} }; 1444 1443 branchStmt = ast::mutate_field( 1445 branchStmt, &ast::BranchStmt::computedTarget, 1444 branchStmt, &ast::BranchStmt::computedTarget, 1446 1445 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1447 1446 } … … 1453 1452 if ( returnStmt->expr ) { 1454 1453 returnStmt = ast::mutate_field( 1455 returnStmt, &ast::ReturnStmt::expr, 1454 returnStmt, &ast::ReturnStmt::expr, 1456 1455 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1457 1456 } … … 1462 1461 visit_children = false; 1463 1462 if ( throwStmt->expr ) { 1464 const ast::StructDecl * exceptionDecl = 1463 const ast::StructDecl * exceptionDecl = 1465 1464 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1466 1465 assert( exceptionDecl ); 1467 ast::ptr< ast::Type > exceptType = 1466 ast::ptr< ast::Type > exceptType = 1468 1467 new ast::PointerType{ new ast::StructInstType{ exceptionDecl } }; 1469 1468 throwStmt = ast::mutate_field( 1470 throwStmt, &ast::ThrowStmt::expr, 1469 throwStmt, &ast::ThrowStmt::expr, 1471 1470 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1472 1471 } … … 1477 1476 if ( catchStmt->cond ) { 1478 1477 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1479 catchStmt = ast::mutate_field( 1480 catchStmt, &ast::CatchStmt::cond, 1478 catchStmt = ast::mutate_field( 1479 catchStmt, &ast::CatchStmt::cond, 1481 1480 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1482 1481 } … … 1506 1505 1507 1506 if ( clause.target.args.empty() ) { 1508 SemanticError( stmt->location, 1507 SemanticError( stmt->location, 1509 1508 "Waitfor clause must have at least one mutex parameter"); 1510 1509 } 1511 1510 1512 1511 // Find all alternatives for all arguments in canonical form 1513 std::vector< CandidateFinder > argFinders = 1512 std::vector< CandidateFinder > argFinders = 1514 1513 funcFinder.findSubExprs( clause.target.args ); 1515 1514 1516 1515 // List all combinations of arguments 1517 1516 std::vector< CandidateList > possibilities; … … 1519 1518 1520 1519 // For every possible function: 1521 // * try matching the arguments to the parameters, not the other way around because 1520 // * try matching the arguments to the parameters, not the other way around because 1522 1521 // more arguments than parameters 1523 1522 CandidateList funcCandidates; … … 1526 1525 for ( CandidateRef & func : funcFinder.candidates ) { 1527 1526 try { 1528 auto pointerType = dynamic_cast< const ast::PointerType * >( 1527 auto pointerType = dynamic_cast< const ast::PointerType * >( 1529 1528 func->expr->result->stripReferences() ); 1530 1529 if ( ! pointerType ) { 1531 SemanticError( stmt->location, func->expr->result.get(), 1530 SemanticError( stmt->location, func->expr->result.get(), 1532 1531 "candidate not viable: not a pointer type\n" ); 1533 1532 } … … 1535 1534 auto funcType = pointerType->base.as< ast::FunctionType >(); 1536 1535 if ( ! funcType ) { 1537 SemanticError( stmt->location, func->expr->result.get(), 1536 SemanticError( stmt->location, func->expr->result.get(), 1538 1537 "candidate not viable: not a function type\n" ); 1539 1538 } … … 1544 1543 1545 1544 if( ! nextMutex( param, paramEnd ) ) { 1546 SemanticError( stmt->location, funcType, 1545 SemanticError( stmt->location, funcType, 1547 1546 "candidate function not viable: no mutex parameters\n"); 1548 1547 } … … 1560 1559 ast::AssertionSet need, have; 1561 1560 ast::TypeEnvironment resultEnv{ func->env }; 1562 // Add all type variables as open so that those not used in the 1561 // Add all type variables as open so that those not used in the 1563 1562 // parameter list are still considered open 1564 1563 resultEnv.add( funcType->forall ); … … 1580 1579 unsigned n_mutex_param = 0; 1581 1580 1582 // For every argument of its set, check if it matches one of the 1581 // For every argument of its set, check if it matches one of the 1583 1582 // parameters. The order is important 1584 1583 for ( auto & arg : argsList ) { … … 1587 1586 // We ran out of parameters but still have arguments. 1588 1587 // This function doesn't match 1589 SemanticError( stmt->location, funcType, 1588 SemanticError( stmt->location, funcType, 1590 1589 toString("candidate function not viable: too many mutex " 1591 1590 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1594 1593 ++n_mutex_param; 1595 1594 1596 // Check if the argument matches the parameter type in the current 1595 // Check if the argument matches the parameter type in the current 1597 1596 // scope 1598 1597 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1599 if ( 1600 ! unify( 1601 arg->expr->result, paramType, resultEnv, need, have, open, 1602 symtab ) 1598 if ( 1599 ! unify( 1600 arg->expr->result, paramType, resultEnv, need, have, open, 1601 symtab ) 1603 1602 ) { 1604 1603 // Type doesn't match … … 1627 1626 } while ( nextMutex( param, paramEnd ) ); 1628 1627 1629 // We ran out of arguments but still have parameters left; this 1628 // We ran out of arguments but still have parameters left; this 1630 1629 // function doesn't match 1631 SemanticError( stmt->location, funcType, 1630 SemanticError( stmt->location, funcType, 1632 1631 toString( "candidate function not viable: too few mutex " 1633 1632 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1657 1656 // Make sure correct number of arguments 1658 1657 if( funcCandidates.empty() ) { 1659 SemanticErrorException top( stmt->location, 1658 SemanticErrorException top( stmt->location, 1660 1659 "No alternatives for function in call to waitfor" ); 1661 1660 top.append( errors ); … … 1664 1663 1665 1664 if( argsCandidates.empty() ) { 1666 SemanticErrorException top( stmt->location, 1667 "No alternatives for arguments in call to waitfor" ); 1665 SemanticErrorException top( stmt->location, 1666 "No alternatives for arguments in call to waitfor" ); 1668 1667 top.append( errors ); 1669 1668 throw top; … … 1671 1670 1672 1671 if( funcCandidates.size() > 1 ) { 1673 SemanticErrorException top( stmt->location, 1672 SemanticErrorException top( stmt->location, 1674 1673 "Ambiguous function in call to waitfor" ); 1675 1674 top.append( errors ); … … 1686 1685 // build new clause 1687 1686 ast::WaitForStmt::Clause clause2; 1688 1687 1689 1688 clause2.target.func = funcCandidates.front()->expr; 1690 1689 1691 1690 clause2.target.args.reserve( clause.target.args.size() ); 1692 1691 for ( auto arg : argsCandidates.front() ) { … … 1708 1707 ast::WaitForStmt::Timeout timeout2; 1709 1708 1710 ast::ptr< ast::Type > target = 1709 ast::ptr< ast::Type > target = 1711 1710 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1712 1711 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); … … 1740 1739 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1741 1740 visit_children = false; 1742 // resolve initialization using the possibilities as determined by the `currentObject` 1741 // resolve initialization using the possibilities as determined by the `currentObject` 1743 1742 // cursor. 1744 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1743 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1745 1744 singleInit->location, singleInit->value, currentObject.getOptions() }; 1746 1745 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); … … 1751 1750 1752 1751 // discard InitExpr wrapper and retain relevant pieces. 1753 // `initExpr` may have inferred params in the case where the expression specialized a 1754 // function pointer, and newExpr may already have inferParams of its own, so a simple 1752 // `initExpr` may have inferred params in the case where the expression specialized a 1753 // function pointer, and newExpr may already have inferParams of its own, so a simple 1755 1754 // swap is not sufficient 1756 1755 ast::Expr::InferUnion inferred = initExpr->inferred; … … 1758 1757 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1759 1758 1760 // get the actual object's type (may not exactly match what comes back from the resolver 1759 // get the actual object's type (may not exactly match what comes back from the resolver 1761 1760 // due to conversions) 1762 1761 const ast::Type * initContext = currentObject.getCurrentType(); … … 1770 1769 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1771 1770 if ( isCharType( pt->base ) ) { 1772 // strip cast if we're initializing a char[] with a char* 1771 // strip cast if we're initializing a char[] with a char* 1773 1772 // e.g. char x[] = "hello" 1774 1773 if ( auto ce = newExpr.as< ast::CastExpr >() ) { … … 1793 1792 assert( listInit->designations.size() == listInit->initializers.size() ); 1794 1793 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1795 // iterate designations and initializers in pairs, moving the cursor to the current 1794 // iterate designations and initializers in pairs, moving the cursor to the current 1796 1795 // designated object and resolving the initializer against that object 1797 1796 listInit = ast::mutate_field_index( 1798 listInit, &ast::ListInit::designations, i, 1797 listInit, &ast::ListInit::designations, i, 1799 1798 currentObject.findNext( listInit->designations[i] ) ); 1800 1799 listInit = ast::mutate_field_index( … … 1818 1817 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr ); 1819 1818 1820 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1821 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1819 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1820 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1822 1821 // clean up generated code 1823 1822 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) { -
src/ResolvExpr/Unify.cc
r1f1c102 rf53acdf8 97 97 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 98 98 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 102 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 103 104 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {104 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 105 105 TypeEnvironment newEnv; 106 106 OpenVarSet openVars, closedVars; // added closedVars 107 107 AssertionSet needAssertions, haveAssertions; 108 Type * newFirst = first->clone(), *newSecond = second->clone();108 Type * newFirst = first->clone(), * newSecond = second->clone(); 109 109 env.apply( newFirst ); 110 110 env.apply( newSecond ); … … 121 121 } 122 122 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 125 125 const ast::TypeEnvironment & env ) { 126 126 ast::TypeEnvironment newEnv; … … 135 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 136 137 return unifyExact( 137 return unifyExact( 138 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 139 } 140 140 141 bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {141 bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 142 142 TypeEnvironment newEnv; 143 143 OpenVarSet openVars; … … 163 163 } 164 164 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 167 167 const ast::TypeEnvironment & env ) { 168 168 ast::TypeEnvironment newEnv; 169 169 ast::OpenVarSet open; 170 170 ast::AssertionSet need, have; 171 171 172 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 173 env.apply( newFirst ); … … 176 176 reset_qualifiers( newSecond ); 177 177 178 return unifyExact( 178 return unifyExact( 179 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 180 180 } … … 490 490 491 491 // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 497 497 ) { 498 498 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { … … 711 711 bool result; 712 712 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 716 716 const ast::SymbolTable & symtab ) 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 718 718 symtab(symtab), result(false) {} 719 719 720 720 void previsit( const ast::Node * ) { visit_children = false; } 721 721 722 722 void postvisit( const ast::VoidType * ) { 723 723 result = dynamic_cast< const ast::VoidType * >( type2 ); … … 732 732 void postvisit( const ast::PointerType * pointer ) { 733 733 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 736 736 noWiden(), symtab ); 737 737 } … … 742 742 if ( ! array2 ) return; 743 743 744 // to unify, array types must both be VLA or both not VLA and both must have a 744 // to unify, array types must both be VLA or both not VLA and both must have a 745 745 // dimension expression or not have a dimension 746 746 if ( array->isVarLen != array2->isVarLen ) return; 747 if ( ! array->isVarLen && ! array2->isVarLen 747 if ( ! array->isVarLen && ! array2->isVarLen 748 748 && array->dimension && array2->dimension ) { 749 749 auto ce1 = array->dimension.as< ast::ConstantExpr >(); … … 751 751 752 752 // see C11 Reference Manual 6.7.6.2.6 753 // two array types with size specifiers that are integer constant expressions are 753 // two array types with size specifiers that are integer constant expressions are 754 754 // compatible if both size specifiers have the same constant value 755 755 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return; 756 756 } 757 757 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 760 760 symtab ); 761 761 } … … 763 763 void postvisit( const ast::ReferenceType * ref ) { 764 764 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 767 767 symtab ); 768 768 } … … 771 771 private: 772 772 /// Replaces ttype variables with their bound types. 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 774 774 /// different size and structure when they should be compatible. 775 775 struct TtypeExpander_new : public ast::WithShortCircuiting { … … 800 800 auto types = flatten( d->get_type() ); 801 801 for ( ast::ptr< ast::Type > & t : types ) { 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 804 804 // whether a function is callable. 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 807 807 // requirements than a non-mutex function 808 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); … … 818 818 std::vector< ast::ptr< ast::Type > > types; 819 819 while ( crnt != end ) { 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 821 821 // that this results in a flat tuple 822 822 flatten( (*crnt)->get_type(), types ); … … 829 829 830 830 template< typename Iter > 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 834 834 const ast::SymbolTable & symtab 835 835 ) { … … 843 843 if ( isTuple1 && ! isTuple2 ) { 844 844 // combine remainder of list2, then unify 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 847 847 noWiden(), symtab ); 848 848 } else if ( ! isTuple1 && isTuple2 ) { 849 849 // combine remainder of list1, then unify 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 852 852 noWiden(), symtab ); 853 853 } 854 854 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 857 857 ) return false; 858 858 … … 860 860 } 861 861 862 // May get to the end of one argument list before the other. This is only okay if the 862 // May get to the end of one argument list before the other. This is only okay if the 863 863 // other is a ttype 864 864 if ( crnt1 != end1 ) { … … 866 866 const ast::Type * t1 = (*crnt1)->get_type(); 867 867 if ( ! Tuples::isTtype( t1 ) ) return false; 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 870 870 noWiden(), symtab ); 871 871 } else if ( crnt2 != end2 ) { … … 873 873 const ast::Type * t2 = (*crnt2)->get_type(); 874 874 if ( ! Tuples::isTtype( t2 ) ) return false; 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 877 877 noWiden(), symtab ); 878 878 } … … 881 881 } 882 882 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 887 887 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 888 888 ) { 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 891 891 symtab ); 892 892 } … … 900 900 901 901 /// mark all assertions in `type` used in both `assn1` and `assn2` 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 905 905 ) { 906 906 for ( const auto & tyvar : type->forall ) { … … 918 918 919 919 if ( func->isVarArgs != func2->isVarArgs ) return; 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 922 922 // affect unification. Does not actually mutate function parameters. 923 923 auto params = flattenList( func->params, tenv ); 924 924 auto params2 = flattenList( func2->params, tenv ); 925 925 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 927 927 // where the ttype is to prevent errors 928 if ( 928 if ( 929 929 ( params.size() != params2.size() || func->returns.size() != func2->returns.size() ) 930 930 && ! func->isTtype() … … 933 933 934 934 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 935 if ( ! unifyDeclList( 935 if ( ! unifyDeclList( 936 936 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 937 937 938 938 markAssertions( have, need, func ); 939 939 markAssertions( have, need, func2 ); … … 941 941 result = true; 942 942 } 943 943 944 944 private: 945 945 template< typename RefType > … … 953 953 /// Creates a tuple type based on a list of TypeExpr 954 954 template< typename Iter > 955 static const ast::Type * tupleFromExprs( 955 static const ast::Type * tupleFromExprs( 956 956 const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs 957 957 ) { … … 973 973 const RefType * inst2 = handleRefType( inst, other ); 974 974 if ( ! inst2 ) return; 975 975 976 976 // check that parameters of types unify, if any 977 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; … … 1002 1002 } 1003 1003 1004 if ( ! unifyExact( 1004 if ( ! unifyExact( 1005 1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1006 1006 result = false; … … 1038 1038 private: 1039 1039 /// Creates a tuple type based on a list of Type 1040 static ast::ptr< ast::Type > tupleFromTypes( 1040 static ast::ptr< ast::Type > tupleFromTypes( 1041 1041 const std::vector< ast::ptr< ast::Type > > & tys 1042 1042 ) { 1043 1043 std::vector< ast::ptr< ast::Type > > out; 1044 1044 for ( const ast::Type * ty : tys ) { 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1046 1046 // that this results in a flat tuple 1047 1047 flatten( ty, out ); … … 1051 1051 } 1052 1052 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1057 1057 const ast::SymbolTable & symtab 1058 1058 ) { … … 1068 1068 if ( isTuple1 && ! isTuple2 ) { 1069 1069 // combine entirety of list2, then unify 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1072 1072 noWiden(), symtab ); 1073 1073 } else if ( ! isTuple1 && isTuple2 ) { 1074 1074 // combine entirety of list1, then unify 1075 1075 return unifyExact( 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1077 1077 noWiden(), symtab ); 1078 1078 } 1079 1079 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1082 1082 ) return false; 1083 1083 … … 1089 1089 const ast::Type * t1 = *crnt1; 1090 1090 if ( ! Tuples::isTtype( t1 ) ) return false; 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1092 1092 // from Rob's code 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1095 1095 noWiden(), symtab ); 1096 1096 } else if ( crnt2 != list2.end() ) { … … 1098 1098 const ast::Type * t2 = *crnt2; 1099 1099 if ( ! Tuples::isTtype( t2 ) ) return false; 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1101 1101 // from Rob's code 1102 1102 return unifyExact( 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1104 1104 noWiden(), symtab ); 1105 1105 } … … 1133 1133 void postvisit( const ast::OneType * ) { 1134 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1135 } 1135 } 1136 1136 1137 1137 private: … … 1140 1140 }; 1141 1141 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1145 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1146 1146 ) { … … 1149 1149 } 1150 1150 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1155 1155 ) { 1156 1156 ast::OpenVarSet closed; 1157 1157 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1158 1158 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1159 return unifyInexact( 1159 return unifyInexact( 1160 1160 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1161 1161 } 1162 1162 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1166 1166 WidenMode widen, const ast::SymbolTable & symtab 1167 1167 ) { … … 1170 1170 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1171 1171 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1174 1174 entry2 = var2 ? open.find( var2->name ) : open.end(); 1175 1175 bool isopen1 = entry1 != open.end(); … … 1178 1178 if ( isopen1 && isopen2 ) { 1179 1179 if ( entry1->second.kind != entry2->second.kind ) return false; 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1182 1182 open, widen, symtab ); 1183 1183 } else if ( isopen1 ) { … … 1192 1192 } 1193 1193 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1199 1199 ) { 1200 1200 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1203 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 1205 reset_qualifiers( t1 ); 1206 1206 reset_qualifiers( t2 ); 1207 1207 1208 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones -
src/ResolvExpr/typeops.h
r1f1c102 rf53acdf8 28 28 #include "SynTree/SynTree.h" 29 29 #include "SynTree/Type.h" 30 #include "SymTab/Indexer.h" 30 31 namespace SymTab { 32 class Indexer; 33 } 31 34 32 35 namespace ResolvExpr { … … 60 63 // in AdjustExprType.cc 61 64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function 62 void adjustExprType( Type *& type, const TypeEnvironment &env, const SymTab::Indexer &indexer );65 void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 63 66 64 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer … … 66 69 67 70 template< typename ForwardIterator > 68 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) { 69 72 while ( begin != end ) { 70 73 adjustExprType( *begin++, env, indexer ); … … 73 76 74 77 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 75 const ast::Type * adjustExprType( 78 const ast::Type * adjustExprType( 76 79 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 77 80 78 81 // in CastCost.cc 79 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );80 Cost castCost( 81 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 82 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 83 Cost castCost( 84 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 82 85 const ast::TypeEnvironment & env ); 83 86 84 87 // in ConversionCost.cc 85 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 88 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 89 Cost conversionCost( 90 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 88 91 const ast::TypeEnvironment & env ); 89 92 90 93 // in AlternativeFinder.cc 91 Cost computeConversionCost( Type * actualType, Type *formalType,92 const SymTab::Indexer & indexer, const TypeEnvironment &env );94 Cost computeConversionCost( Type * actualType, Type * formalType, 95 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 93 96 94 97 // in PtrsAssignable.cc 95 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );98 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env ); 96 99 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 97 100 const ast::TypeEnvironment & env ); 98 101 99 102 // in PtrsCastable.cc 100 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );101 int ptrsCastable( 102 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 103 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 104 int ptrsCastable( 105 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 103 106 const ast::TypeEnvironment & env ); 104 107 105 108 // in Unify.cc 106 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );107 bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );108 109 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {109 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 110 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 111 112 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 110 113 TypeEnvironment env; 111 114 return typesCompatible( t1, t2, indexer, env ); 112 115 } 113 116 114 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {117 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 115 118 TypeEnvironment env; 116 119 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 117 120 } 118 121 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 122 bool typesCompatible( 123 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 121 124 const ast::TypeEnvironment & env = {} ); 122 125 123 126 bool typesCompatibleIgnoreQualifiers( 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 127 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 125 128 const ast::TypeEnvironment & env = {} ); 126 129 … … 131 134 132 135 // in CommonType.cc 133 Type * commonType( Type * type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );136 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars ); 134 137 ast::ptr< ast::Type > commonType( 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 138 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 136 139 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 137 140 138 141 // in PolyCost.cc 139 int polyCost( Type * type, const TypeEnvironment &env, const SymTab::Indexer &indexer );140 int polyCost( 142 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 143 int polyCost( 141 144 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 142 145 143 146 // in SpecCost.cc 144 int specCost( Type * type );147 int specCost( Type * type ); 145 148 int specCost( const ast::Type * type ); 146 149 147 150 // in Occurs.cc 148 bool occurs( Type * type, std::string varName, const TypeEnvironment &env );151 bool occurs( Type * type, std::string varName, const TypeEnvironment & env ); 149 152 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 150 153 151 template<typename Iter> 152 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {154 template<typename Iter> 155 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) { 153 156 while ( begin != end ) { 154 157 if ( occurs( ty, *begin, env ) ) return true; … … 176 179 177 180 /// flatten tuple type into existing list of types 178 static inline void flatten( 179 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 181 static inline void flatten( 182 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 180 183 ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 184 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 182 185 for ( const ast::Type * t : tupleType->types ) { 183 186 flatten( t, out ); … … 197 200 198 201 // in TypeEnvironment.cc 199 bool isFtype( Type * type );202 bool isFtype( Type * type ); 200 203 } // namespace ResolvExpr 201 204
Note:
See TracChangeset
for help on using the changeset viewer.