Changes in src/ResolvExpr/CastCost.cc [c6b4432:251ce80]
- File:
-
- 1 edited
-
src/ResolvExpr/CastCost.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
rc6b4432 r251ce80 26 26 #include "ResolvExpr/ConversionCost.h" // for conversionCost 27 27 #include "ResolvExpr/PtrsCastable.hpp" // for ptrsCastable 28 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment, EqvClass 28 29 #include "ResolvExpr/typeops.h" // for ptrsCastable 29 30 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 31 #include "SymTab/Indexer.h" // for Indexer 32 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 33 #include "SynTree/Type.h" // for PointerType, Type, TypeInstType 30 34 31 35 #if 0 … … 36 40 37 41 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 47 using ConversionCost::previsit; 48 using ConversionCost::postvisit; 49 void postvisit( const BasicType * basicType ); 50 void postvisit( const PointerType * pointerType ); 51 }; 52 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 } 38 142 39 143 namespace { … … 96 200 } // anonymous namespace 97 201 202 203 98 204 Cost castCost( 99 205 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, … … 128 234 if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) { 129 235 PRINT( std::cerr << "compatible!" << std::endl; ) 130 if (dynamic_cast<const ast::ZeroType *>(dst) || dynamic_cast<const ast::OneType *>(dst)) {131 return Cost::spec;132 }133 236 return Cost::zero; 134 237 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
Note:
See TracChangeset
for help on using the changeset viewer.