Changes in src/ResolvExpr/CastCost.cc [7d01cf44:00ac42e]
- File:
-
- 1 edited
-
src/ResolvExpr/CastCost.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
r7d01cf44 r00ac42e 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 06:57:43 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : T hu Aug 8 16:12:00 201913 // Update Count : 811 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 2 15:34:36 2016 13 // Update Count : 7 14 14 // 15 15 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"22 18 #include "ConversionCost.h" // for ConversionCost 23 19 #include "Cost.h" // for Cost, Cost::infinity … … 35 31 36 32 namespace ResolvExpr { 37 struct CastCost _old: public ConversionCost {33 struct CastCost : public ConversionCost { 38 34 public: 39 CastCost_old( const Type * dest, bool srcIsLvalue, 40 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 35 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 41 36 42 37 using ConversionCost::previsit; 43 38 using ConversionCost::postvisit; 44 void postvisit( constBasicType * basicType );45 void postvisit( constPointerType * pointerType );39 void postvisit( BasicType * basicType ); 40 void postvisit( PointerType * pointerType ); 46 41 }; 47 42 48 Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue, 49 const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 43 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 44 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 45 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 52 46 if ( eqvClass->type ) { 53 return castCost( src, eqvClass->type, srcIsLvalue,indexer, env );47 return castCost( src, eqvClass->type, indexer, env ); 54 48 } else { 55 49 return Cost::infinity; 56 50 } 57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name) ) {51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) { 58 52 // all typedefs should be gone by this point 59 const TypeDecl * type = strict_dynamic_cast< const TypeDecl* >( namedType );53 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType ); 60 54 if ( type->base ) { 61 return castCost( src, type->base, srcIsLvalue,indexer, env ) + Cost::safe;55 return castCost( src, type->base, indexer, env ) + Cost::safe; 62 56 } // if 63 57 } // if … … 76 70 PRINT( std::cerr << "compatible!" << std::endl; ) 77 71 return Cost::zero; 78 } else if ( dynamic_cast< const VoidType* >( dest ) ) {72 } else if ( dynamic_cast< VoidType* >( dest ) ) { 79 73 return Cost::safe; 80 } else if ( const ReferenceType * refType = dynamic_cast< constReferenceType * > ( dest ) ) {74 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 81 75 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 82 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, constType * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {76 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 83 77 return ptrsCastable( t1, t2, env, indexer ); 84 78 }); 85 79 } else { 86 PassVisitor<CastCost_old> converter( 87 dest, srcIsLvalue, indexer, env, 88 (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & )) 89 castCost ); 80 PassVisitor<CastCost> converter( dest, indexer, env, castCost ); 90 81 src->accept( converter ); 91 82 if ( converter.pass.get_cost() == Cost::infinity ) { … … 98 89 } 99 90 100 CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue, 101 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 102 : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) { 91 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 92 : ConversionCost( dest, indexer, env, costFunc ) { 103 93 } 104 94 105 void CastCost _old::postvisit( const BasicType *basicType ) {106 const PointerType * destAsPointer = dynamic_cast< const PointerType* >( dest );95 void CastCost::postvisit( BasicType *basicType ) { 96 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest ); 107 97 if ( destAsPointer && basicType->isInteger() ) { 108 // necessary for, e.g. unsigned long => void *98 // necessary for, e.g. unsigned long => void* 109 99 cost = Cost::unsafe; 110 100 } else { 111 cost = conversionCost( basicType, dest, srcIsLvalue,indexer, env );101 cost = conversionCost( basicType, dest, indexer, env ); 112 102 } // if 113 103 } 114 104 115 void CastCost _old::postvisit( const PointerType *pointerType ) {116 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType* >( dest ) ) {117 if ( pointerType-> tq <= destAsPtr->tq&& typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {105 void CastCost::postvisit( PointerType *pointerType ) { 106 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 107 if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 118 108 cost = Cost::safe; 119 109 } else { … … 128 118 } // if 129 119 } // if 130 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {120 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 131 121 if ( destAsBasic->isInteger() ) { 132 // necessary for, e.g. void * => unsigned long122 // necessary for, e.g. void* => unsigned long 133 123 cost = Cost::unsafe; 134 124 } // if 135 125 } 136 126 } 137 138 namespace {139 struct CastCost_new : public ConversionCost_new {140 using ConversionCost_new::previsit;141 using ConversionCost_new::postvisit;142 143 CastCost_new(144 const ast::Type * dst, const ast::SymbolTable & symtab,145 const ast::TypeEnvironment & env, CostCalculation costFunc )146 : ConversionCost_new( dst, symtab, env, costFunc ) {}147 148 void postvisit( const ast::BasicType * basicType ) {149 auto ptr = dynamic_cast< const ast::PointerType * >( dst );150 if ( ptr && basicType->isInteger() ) {151 // needed for, e.g. unsigned long => void *152 cost = Cost::unsafe;153 } else {154 cost = conversionCost( basicType, dst, symtab, env );155 }156 }157 158 void postvisit( const ast::PointerType * pointerType ) {159 if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) {160 if (161 pointerType->qualifiers <= ptr->qualifiers162 && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env )163 ) {164 cost = Cost::safe;165 } else {166 ast::TypeEnvironment newEnv{ env };167 if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) {168 newEnv.add( wParams->forall );169 }170 int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv );171 if ( castResult > 0 ) {172 cost = Cost::safe;173 } else if ( castResult < 0 ) {174 cost = Cost::infinity;175 }176 }177 } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) {178 if ( basic->isInteger() ) {179 // necessary for, e.g. void * => unsigned long180 cost = Cost::unsafe;181 }182 }183 }184 };185 } // anonymous namespace186 187 Cost castCost(188 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,189 const ast::TypeEnvironment & env190 ) {191 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {192 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) {193 // check cast cost against bound type, if present194 if ( eqvClass->bound ) {195 return castCost( src, eqvClass->bound, symtab, env );196 } else {197 return Cost::infinity;198 }199 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) {200 // all typedefs should be gone by now201 auto type = strict_dynamic_cast< const ast::TypeDecl * >( named );202 if ( type->base ) {203 return castCost( src, type->base, symtab, env ) + Cost::safe;204 }205 }206 }207 208 PRINT(209 std::cerr << "castCost ::: src is ";210 ast::print( std::cerr, src );211 std::cerr << std::endl << "dest is ";212 ast::print( std::cerr, dst );213 std::cerr << std::endl << "env is" << std::endl;214 ast::print( std::cerr, env, 2 );215 )216 217 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {218 PRINT( std::cerr << "compatible!" << std::endl; )219 return Cost::zero;220 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {221 return Cost::safe;222 } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) {223 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )224 #warning cast on ptrsCastable artifact of having two functions, remove when port done225 return convertToReferenceCost(226 src, refType, symtab, env,227 ( int (*)(228 const ast::Type *, const ast::Type *, const ast::SymbolTable &,229 const ast::TypeEnvironment & )230 ) ptrsCastable );231 } else {232 #warning cast on castCost artifact of having two functions, remove when port done233 ast::Pass< CastCost_new > converter{234 dst, symtab, env,235 ( Cost (*)(236 const ast::Type *, const ast::Type *, const ast::SymbolTable &,237 const ast::TypeEnvironment & )238 ) castCost };239 src->accept( converter );240 return converter.pass.cost;241 }242 }243 244 127 } // namespace ResolvExpr 245 128
Note:
See TracChangeset
for help on using the changeset viewer.