Changes in src/ResolvExpr/CastCost.cc [c8e4d2f8:3c89751]
- File:
-
- 1 edited
-
src/ResolvExpr/CastCost.cc (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
rc8e4d2f8 r3c89751 16 16 #include <cassert> // for assert 17 17 18 #include "AST/Print.hpp" 19 #include "AST/SymbolTable.hpp" 20 #include "AST/Type.hpp" 21 #include "AST/TypeEnvironment.hpp" 18 22 #include "ConversionCost.h" // for ConversionCost 19 23 #include "Cost.h" // for Cost, Cost::infinity … … 31 35 32 36 namespace ResolvExpr { 33 struct CastCost : public ConversionCost {37 struct CastCost_old : public ConversionCost { 34 38 public: 35 CastCost ( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );39 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 36 40 37 41 using ConversionCost::previsit; … … 78 82 }); 79 83 } else { 80 #warning cast on castCost artifact of having two functions, remove when port done 81 PassVisitor<CastCost> converter( 84 PassVisitor<CastCost_old> converter( 82 85 dest, indexer, env, 83 86 (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & )) … … 93 96 } 94 97 95 CastCost ::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )98 CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 96 99 : ConversionCost( dest, indexer, env, costFunc ) { 97 100 } 98 101 99 void CastCost ::postvisit( BasicType *basicType ) {102 void CastCost_old::postvisit( BasicType *basicType ) { 100 103 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest ); 101 104 if ( destAsPointer && basicType->isInteger() ) { … … 107 110 } 108 111 109 void CastCost ::postvisit( PointerType *pointerType ) {112 void CastCost_old::postvisit( PointerType *pointerType ) { 110 113 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 111 114 if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { … … 130 133 } 131 134 132 Cost castCost( 133 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 134 const ast::TypeEnvironment & env 135 ) { 136 #warning unimplmented 137 (void)src; (void)dst; (void)symtab; (void)env; 138 assert(false); 135 namespace { 136 struct CastCost_new : public ConversionCost_new { 137 using ConversionCost_new::previsit; 138 using ConversionCost_new::postvisit; 139 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 142 const ast::TypeEnvironment & env, CostCalculation costFunc ) 143 : ConversionCost_new( dst, symtab, env, costFunc ) {} 144 145 void postvisit( const ast::BasicType * basicType ) { 146 auto ptr = dynamic_cast< const ast::PointerType * >( dst ); 147 if ( ptr && basicType->isInteger() ) { 148 // needed for, e.g. unsigned long => void * 149 cost = Cost::unsafe; 150 } else { 151 cost = conversionCost( basicType, dst, symtab, env ); 152 } 153 } 154 155 void postvisit( const ast::PointerType * pointerType ) { 156 if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) { 157 if ( 158 pointerType->qualifiers <= ptr->qualifiers 159 && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env ) 160 ) { 161 cost = Cost::safe; 162 } else { 163 ast::TypeEnvironment newEnv{ env }; 164 if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) { 165 newEnv.add( wParams->forall ); 166 } 167 int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv ); 168 if ( castResult > 0 ) { 169 cost = Cost::safe; 170 } else if ( castResult < 0 ) { 171 cost = Cost::infinity; 172 } 173 } 174 } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) { 175 if ( basic->isInteger() ) { 176 // necessary for, e.g. void * => unsigned long 177 cost = Cost::unsafe; 178 } 179 } 180 } 181 }; 182 } // anonymous namespace 183 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 187 ) { 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 189 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) { 190 // check cast cost against bound type, if present 191 if ( eqvClass->bound ) { 192 return castCost( src, eqvClass->bound, symtab, env ); 193 } else { 194 return Cost::infinity; 195 } 196 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) { 197 // all typedefs should be gone by now 198 auto type = strict_dynamic_cast< const ast::TypeDecl * >( named ); 199 if ( type->base ) { 200 return castCost( src, type->base, symtab, env ) + Cost::safe; 201 } 202 } 203 } 204 205 PRINT( 206 std::cerr << "castCost ::: src is "; 207 ast::print( std::cerr, src ); 208 std::cerr << std::endl << "dest is "; 209 ast::print( std::cerr, dst ); 210 std::cerr << std::endl << "env is" << std::endl; 211 ast::print( std::cerr, env, 2 ); 212 ) 213 214 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) { 215 PRINT( std::cerr << "compatible!" << std::endl; ) 139 216 return Cost::zero; 140 } 217 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 218 return Cost::safe; 219 } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) { 220 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 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 &, 226 const ast::TypeEnvironment & ) 227 ) ptrsCastable ); 228 } else { 229 #warning cast on castCost artifact of having two functions, remove when port done 230 ast::Pass< CastCost_new > converter{ 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 234 const ast::TypeEnvironment & ) 235 ) castCost }; 236 src->accept( converter ); 237 return converter.pass.cost; 238 } 239 } 240 141 241 } // namespace ResolvExpr 142 242
Note:
See TracChangeset
for help on using the changeset viewer.