Changeset b067d9b for src/ResolvExpr/CastCost.cc
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (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
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 06:57:43 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Feb 2 15:34:36 201613 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:12:00 2019 13 // Update Count : 8 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" 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( const Type * dest, bool srcIsLvalue, 40 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 36 41 37 42 using ConversionCost::previsit; 38 43 using ConversionCost::postvisit; 39 void postvisit( BasicType * basicType );40 void postvisit( PointerType * pointerType );44 void postvisit( const BasicType * basicType ); 45 void postvisit( const PointerType * pointerType ); 41 46 }; 42 47 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() ) ) { 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 ) ) { 46 52 if ( eqvClass->type ) { 47 return castCost( src, eqvClass->type, indexer, env );53 return castCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 48 54 } else { 49 55 return Cost::infinity; 50 56 } 51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name()) ) {57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 52 58 // all typedefs should be gone by this point 53 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );59 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 54 60 if ( type->base ) { 55 return castCost( src, type->base, indexer, env ) + Cost::safe;61 return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe; 56 62 } // if 57 63 } // if … … 70 76 PRINT( std::cerr << "compatible!" << std::endl; ) 71 77 return Cost::zero; 72 } else if ( dynamic_cast< VoidType* >( dest ) ) {78 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 73 79 return Cost::safe; 74 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {80 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 75 81 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 76 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1,Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {82 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 77 83 return ptrsCastable( t1, t2, env, indexer ); 78 84 }); 79 85 } else { 80 PassVisitor<CastCost> converter( dest, indexer, env, castCost ); 86 PassVisitor<CastCost_old> converter( 87 dest, srcIsLvalue, indexer, env, 88 (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & )) 89 castCost ); 81 90 src->accept( converter ); 82 91 if ( converter.pass.get_cost() == Cost::infinity ) { … … 89 98 } 90 99 91 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 92 : ConversionCost( dest, indexer, env, costFunc ) { 93 } 94 95 void CastCost::postvisit( BasicType *basicType ) { 96 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest ); 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 ) { 103 } 104 105 void CastCost_old::postvisit( const BasicType * basicType ) { 106 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest ); 97 107 if ( destAsPointer && basicType->isInteger() ) { 98 // necessary for, e.g. unsigned long => void *108 // necessary for, e.g. unsigned long => void * 99 109 cost = Cost::unsafe; 100 110 } else { 101 cost = conversionCost( basicType, dest, indexer, env );111 cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env ); 102 112 } // if 103 113 } 104 114 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 ) ) {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 ) ) { 108 118 cost = Cost::safe; 109 119 } else { … … 118 128 } // if 119 129 } // if 120 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {130 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 121 131 if ( destAsBasic->isInteger() ) { 122 // necessary for, e.g. void * => unsigned long132 // necessary for, e.g. void * => unsigned long 123 133 cost = Cost::unsafe; 124 134 } // if 125 135 } 126 136 } 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->qualifiers 162 && 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 long 180 cost = Cost::unsafe; 181 } 182 } 183 } 184 }; 185 } // anonymous namespace 186 187 Cost castCost( 188 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 189 const ast::TypeEnvironment & env 190 ) { 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 present 194 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 now 201 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 done 225 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 done 233 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 127 244 } // namespace ResolvExpr 128 245
Note:
See TracChangeset
for help on using the changeset viewer.