Changeset 8d182b1 for src/ResolvExpr/CastCost.cc
- Timestamp:
- Nov 14, 2023, 12:19:09 PM (23 months ago)
- Branches:
- master
- Children:
- 1ccae59, 89a8bab
- Parents:
- df8ba61a (diff), 5625427 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
rdf8ba61a r8d182b1 26 26 #include "ResolvExpr/ConversionCost.h" // for conversionCost 27 27 #include "ResolvExpr/PtrsCastable.hpp" // for ptrsCastable 28 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment, EqvClass29 #include "ResolvExpr/typeops.h" // for ptrsCastable30 28 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 31 #include "SymTab/Indexer.h" // for Indexer32 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl33 #include "SynTree/Type.h" // for PointerType, Type, TypeInstType34 29 35 30 #if 0 … … 40 35 41 36 namespace ResolvExpr { 42 struct CastCost_old : public ConversionCost {43 public:44 CastCost_old( const Type * dest, bool srcIsLvalue,45 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );46 37 38 namespace { 39 struct CastCost : public ConversionCost { 47 40 using ConversionCost::previsit; 48 41 using ConversionCost::postvisit; 49 void postvisit( const BasicType * basicType );50 void postvisit( const PointerType * pointerType );51 };52 42 53 Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue, 54 const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 55 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 56 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 57 if ( eqvClass->type ) { 58 return castCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 59 } else { 60 return Cost::infinity; 61 } 62 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 63 // all typedefs should be gone by this point 64 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 65 if ( type->base ) { 66 return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe; 67 } // if 68 } // if 69 } // if 70 71 PRINT( 72 std::cerr << "castCost ::: src is "; 73 src->print( std::cerr ); 74 std::cerr << std::endl << "dest is "; 75 dest->print( std::cerr ); 76 std::cerr << std::endl << "env is" << std::endl; 77 env.print( std::cerr, 8 ); 78 ) 79 80 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 81 PRINT( std::cerr << "compatible!" << std::endl; ) 82 return Cost::zero; 83 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 84 return Cost::safe; 85 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 86 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 87 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 88 return ptrsCastable( t1, t2, env, indexer ); 89 }); 90 } else { 91 PassVisitor<CastCost_old> converter( 92 dest, srcIsLvalue, indexer, env, 93 (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & )) 94 castCost ); 95 src->accept( converter ); 96 if ( converter.pass.get_cost() == Cost::infinity ) { 97 return Cost::infinity; 98 } else { 99 // xxx - why are we adding cost 0 here? 100 return converter.pass.get_cost() + Cost::zero; 101 } // if 102 } // if 103 } 104 105 CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue, 106 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 107 : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) { 108 } 109 110 void CastCost_old::postvisit( const BasicType * basicType ) { 111 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest ); 112 if ( destAsPointer && basicType->isInteger() ) { 113 // necessary for, e.g. unsigned long => void * 114 cost = Cost::unsafe; 115 } else { 116 cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env ); 117 } // if 118 } 119 120 void CastCost_old::postvisit( const PointerType * pointerType ) { 121 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 122 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 123 cost = Cost::safe; 124 } else { 125 TypeEnvironment newEnv( env ); 126 newEnv.add( pointerType->forall ); 127 newEnv.add( pointerType->base->forall ); 128 int castResult = ptrsCastable( pointerType->base, destAsPtr->base, newEnv, indexer ); 129 if ( castResult > 0 ) { 130 cost = Cost::safe; 131 } else if ( castResult < 0 ) { 132 cost = Cost::infinity; 133 } // if 134 } // if 135 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 136 if ( destAsBasic->isInteger() ) { 137 // necessary for, e.g. void * => unsigned long 138 cost = Cost::unsafe; 139 } // if 140 } 141 } 142 143 namespace { 144 struct CastCost_new : public ConversionCost_new { 145 using ConversionCost_new::previsit; 146 using ConversionCost_new::postvisit; 147 148 CastCost_new( 43 CastCost( 149 44 const ast::Type * dst, bool srcIsLvalue, const ast::SymbolTable & symtab, 150 45 const ast::TypeEnvironment & env, CostCalculation costFunc ) 151 : ConversionCost _new( dst, srcIsLvalue, symtab, env, costFunc ) {}46 : ConversionCost( dst, srcIsLvalue, symtab, env, costFunc ) {} 152 47 153 48 void postvisit( const ast::BasicType * basicType ) { … … 189 84 }; 190 85 191 #warning For overload resolution between the two versions.192 int localPtrsCastable(const ast::Type * t1, const ast::Type * t2,193 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) {194 return ptrsCastable( t1, t2, symtab, env );195 }196 Cost localCastCost(197 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,198 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env199 ) { return castCost( src, dst, srcIsLvalue, symtab, env ); }200 86 } // anonymous namespace 201 202 203 87 204 88 Cost castCost( … … 242 126 } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) { 243 127 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 244 #warning cast on ptrsCastable artifact of having two functions, remove when port done245 128 return convertToReferenceCost( 246 src, refType, srcIsLvalue, symtab, env, localPtrsCastable );129 src, refType, srcIsLvalue, symtab, env, ptrsCastable ); 247 130 } else { 248 #warning cast on castCost artifact of having two functions, remove when port done 249 ast::Pass< CastCost_new > converter( 250 dst, srcIsLvalue, symtab, env, localCastCost ); 131 ast::Pass< CastCost > converter( 132 dst, srcIsLvalue, symtab, env, castCost ); 251 133 src->accept( converter ); 252 134 return converter.core.cost;
Note:
See TracChangeset
for help on using the changeset viewer.