- Timestamp:
- Jun 24, 2019, 3:42:36 PM (5 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:
- 1335e6f
- Parents:
- 093a5d7
- Location:
- src/ResolvExpr
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
r093a5d7 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 -
src/ResolvExpr/ConversionCost.h
r093a5d7 r3c89751 74 74 const ast::SymbolTable &, const ast::TypeEnvironment &)>; 75 75 76 // TODO: When the old ConversionCost is removed, get ride of the _new suffix.76 #warning when the old ConversionCost is removed, get ride of the _new suffix. 77 77 class ConversionCost_new : public ast::WithShortCircuiting { 78 protected: 78 79 const ast::Type * dst; 79 80 const ast::SymbolTable & symtab; -
src/ResolvExpr/PtrsCastable.cc
r093a5d7 r3c89751 14 14 // 15 15 16 #include "AST/Decl.hpp" 17 #include "AST/Pass.hpp" 18 #include "AST/Type.hpp" 19 #include "AST/TypeEnvironment.hpp" 16 20 #include "Common/PassVisitor.h" 17 21 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 23 27 24 28 namespace ResolvExpr { 25 struct PtrsCastable : public WithShortCircuiting {29 struct PtrsCastable_old : public WithShortCircuiting { 26 30 public: 27 PtrsCastable ( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );31 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 28 32 29 33 int get_result() const { return result; } … … 86 90 return objectCast( src, env, indexer ); 87 91 } else { 88 PassVisitor<PtrsCastable > ptrs( dest, env, indexer );92 PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer ); 89 93 src->accept( ptrs ); 90 94 return ptrs.pass.get_result(); … … 92 96 } 93 97 94 PtrsCastable ::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )98 PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) 95 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 96 100 } 97 101 98 void PtrsCastable ::postvisit( VoidType * ) {99 result = objectCast( dest, env, indexer ); 100 } 101 102 void PtrsCastable ::postvisit( BasicType * ) {103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable ::postvisit( PointerType * ) {107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable ::postvisit( ArrayType * ) {111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable ::postvisit( FunctionType * ) {102 void PtrsCastable_old::postvisit( VoidType * ) { 103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( BasicType * ) { 107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( PointerType * ) { 111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( ArrayType * ) { 115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( FunctionType * ) { 115 119 // result = -1; 116 120 result = functionCast( dest, env, indexer ); 117 121 } 118 122 119 void PtrsCastable ::postvisit( StructInstType * ) {120 result = objectCast( dest, env, indexer ); 121 } 122 123 void PtrsCastable ::postvisit( UnionInstType * ) {124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable ::postvisit( EnumInstType * ) {123 void PtrsCastable_old::postvisit( StructInstType * ) { 124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( UnionInstType * ) { 128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( EnumInstType * ) { 128 132 if ( dynamic_cast< EnumInstType* >( dest ) ) { 129 133 result = 1; … … 139 143 } 140 144 141 void PtrsCastable ::postvisit( TraitInstType * ) {}142 143 void PtrsCastable ::postvisit(TypeInstType *inst) {145 void PtrsCastable_old::postvisit( TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit(TypeInstType *inst ) { 144 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 145 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 146 150 } 147 151 148 void PtrsCastable::postvisit( TupleType * ) { 149 result = objectCast( dest, env, indexer ); 150 } 151 152 void PtrsCastable::postvisit( VarArgsType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable::postvisit( ZeroType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable::postvisit( OneType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 152 void PtrsCastable_old::postvisit( TupleType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( VarArgsType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( ZeroType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( OneType * ) { 165 result = objectCast( dest, env, indexer ); 166 } 167 168 namespace { 169 // can this type be cast to an object (1 for yes, -1 for no) 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 172 ) { 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { 174 return -1; 175 } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) { 176 if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) { 177 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) { 178 if ( tyDecl->kind == ast::TypeVar::Ftype ) { 179 return -1; 180 } 181 } 182 } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) { 183 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) { 184 return -1; 185 } 186 } 187 } 188 189 return 1; 190 } 191 192 // can this type be cast to a function (inverse of objectCast) 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 195 ) { 196 return -1 * objectCast( src, env, symtab ); 197 } 198 199 class PtrsCastable_new : public ast::WithShortCircuiting { 200 const ast::Type * dst; 201 const ast::TypeEnvironment & env; 202 const ast::SymbolTable & symtab; 203 public: 204 int result; 205 206 PtrsCastable_new( 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} 209 210 void previsit( const ast::Type * ) { visit_children = false; } 211 212 void postvisit( const ast::VoidType * ) { 213 result = objectCast( dst, env, symtab ); 214 } 215 216 void postvisit( const ast::BasicType * ) { 217 result = objectCast( dst, env, symtab ); 218 } 219 220 void postvisit( const ast::PointerType * ) { 221 result = objectCast( dst, env, symtab ); 222 } 223 224 void postvisit( const ast::ArrayType * ) { 225 result = objectCast( dst, env, symtab ); 226 } 227 228 void postvisit( const ast::FunctionType * ) { 229 result = functionCast( dst, env, symtab ); 230 } 231 232 void postvisit( const ast::StructInstType * ) { 233 result = objectCast( dst, env, symtab ); 234 } 235 236 void postvisit( const ast::UnionInstType * ) { 237 result = objectCast( dst, env, symtab ); 238 } 239 240 void postvisit( const ast::EnumInstType * ) { 241 if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) { 242 result = 1; 243 } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) { 244 if ( bt->kind == ast::BasicType::SignedInt ) { 245 result = 0; 246 } else { 247 result = 1; 248 } 249 } else { 250 result = objectCast( dst, env, symtab ); 251 } 252 } 253 254 void postvisit( const ast::TraitInstType * ) {} 255 256 void postvisit( const ast::TypeInstType * inst ) { 257 // check trait and destination type are both object or both function 258 result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1; 259 } 260 261 void postvisit( const ast::TupleType * ) { 262 result = objectCast( dst, env, symtab ); 263 } 264 265 void postvisit( const ast::VarArgsType * ) { 266 result = objectCast( dst, env, symtab ); 267 } 268 269 void postvisit( const ast::ZeroType * ) { 270 result = objectCast( dst, env, symtab ); 271 } 272 273 void postvisit( const ast::OneType * ) { 274 result = objectCast( dst, env, symtab ); 275 } 276 277 }; 278 } // anonymous namespace 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 ) { 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 285 if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) { 286 return ptrsAssignable( src, eqvClass->bound, env ); 287 } 288 } 289 290 if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 291 return objectCast( src, env, symtab ); 292 } else { 293 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab }; 294 src->accept( ptrs ); 295 return ptrs.pass.result; 296 } 297 } 298 163 299 } // namespace ResolvExpr 164 300 -
src/ResolvExpr/Resolver.cc
r093a5d7 r3c89751 1337 1337 if ( type->dimension ) { 1338 1338 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1339 ast::ptr< ast::Type > sizeType = 1340 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1339 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1341 1340 ast::mutate_field( 1342 1341 type, &PtrType::dimension, -
src/ResolvExpr/typeops.h
r093a5d7 r3c89751 99 99 // in PtrsCastable.cc 100 100 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 101 int ptrsCastable( 102 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 103 const ast::TypeEnvironment & env ); 101 104 102 105 // in Unify.cc
Note: See TracChangeset
for help on using the changeset viewer.