Changeset 7870799 for src/ResolvExpr
- Timestamp:
- Jul 12, 2019, 10:49:02 AM (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:
- ef5b828
- Parents:
- ee6dbae
- Location:
- src/ResolvExpr
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CastCost.cc
ree6dbae r7870799 37 37 struct CastCost_old : public ConversionCost { 38 38 public: 39 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );39 CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 40 40 41 41 using ConversionCost::previsit; 42 42 using ConversionCost::postvisit; 43 void postvisit( BasicType * basicType );44 void postvisit( PointerType * pointerType );43 void postvisit( const BasicType * basicType ); 44 void postvisit( const PointerType * pointerType ); 45 45 }; 46 46 47 Cost castCost( Type *src,Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {48 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {49 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst-> get_name()) ) {47 Cost castCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 48 if ( const TypeInstType *destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 49 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { 50 50 if ( eqvClass->type ) { 51 51 return castCost( src, eqvClass->type, indexer, env ); … … 53 53 return Cost::infinity; 54 54 } 55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst-> get_name()) ) {55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) { 56 56 // all typedefs should be gone by this point 57 TypeDecl *type = strict_dynamic_cast<TypeDecl* >( namedType );57 const TypeDecl * type = strict_dynamic_cast< const TypeDecl* >( namedType ); 58 58 if ( type->base ) { 59 59 return castCost( src, type->base, indexer, env ) + Cost::safe; … … 74 74 PRINT( std::cerr << "compatible!" << std::endl; ) 75 75 return Cost::zero; 76 } else if ( dynamic_cast< VoidType* >( dest ) ) {76 } else if ( dynamic_cast< const VoidType* >( dest ) ) { 77 77 return Cost::safe; 78 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {78 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 79 79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 80 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {80 return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 81 81 return ptrsCastable( t1, t2, env, indexer ); 82 82 }); 83 83 } else { 84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment & ))84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & )) 87 87 castCost ); 88 88 src->accept( converter ); … … 96 96 } 97 97 98 CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )98 CastCost_old::CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 99 99 : ConversionCost( dest, indexer, env, costFunc ) { 100 100 } 101 101 102 void CastCost_old::postvisit( BasicType *basicType ) {103 PointerType *destAsPointer = dynamic_cast<PointerType* >( dest );102 void CastCost_old::postvisit( const BasicType *basicType ) { 103 const PointerType *destAsPointer = dynamic_cast< const PointerType* >( dest ); 104 104 if ( destAsPointer && basicType->isInteger() ) { 105 105 // necessary for, e.g. unsigned long => void* … … 110 110 } 111 111 112 void CastCost_old::postvisit( PointerType *pointerType ) {113 if ( PointerType *destAsPtr = dynamic_cast<PointerType* >( dest ) ) {114 if ( pointerType-> get_qualifiers() <= destAsPtr->get_qualifiers()&& typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {112 void CastCost_old::postvisit( const PointerType *pointerType ) { 113 if ( const PointerType *destAsPtr = dynamic_cast< const PointerType* >( dest ) ) { 114 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 115 115 cost = Cost::safe; 116 116 } else { … … 125 125 } // if 126 126 } // if 127 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {127 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 128 128 if ( destAsBasic->isInteger() ) { 129 129 // necessary for, e.g. void* => unsigned long … … 138 138 using ConversionCost_new::postvisit; 139 139 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 142 142 const ast::TypeEnvironment & env, CostCalculation costFunc ) 143 143 : ConversionCost_new( dst, symtab, env, costFunc ) {} … … 182 182 } // anonymous namespace 183 183 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 187 187 ) { 188 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 220 220 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 221 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 &, 222 return convertToReferenceCost( 223 src, refType, symtab, env, 224 ( int (*)( 225 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 226 226 const ast::TypeEnvironment & ) 227 227 ) ptrsCastable ); … … 229 229 #warning cast on castCost artifact of having two functions, remove when port done 230 230 ast::Pass< CastCost_new > converter{ 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 234 234 const ast::TypeEnvironment & ) 235 235 ) castCost }; -
src/ResolvExpr/ConversionCost.cc
ree6dbae r7870799 46 46 #endif 47 47 48 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {49 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {48 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 49 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 50 50 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 51 51 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { … … 55 55 return Cost::infinity; 56 56 } 57 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 58 58 PRINT( std::cerr << " found" << std::endl; ) 59 TypeDecl *type = dynamic_cast<TypeDecl* >( namedType );59 const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType ); 60 60 // all typedefs should be gone by this point 61 61 assert( type ); … … 77 77 PRINT( std::cerr << "compatible!" << std::endl; ) 78 78 return Cost::zero; 79 } else if ( dynamic_cast< VoidType* >( dest ) ) {79 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 80 80 return Cost::safe; 81 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {81 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 82 82 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 83 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){83 return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 84 84 return ptrsAssignable( t1, t2, env ); 85 85 }); 86 86 } else { 87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)( Type*,Type*, const SymTab::Indexer&, const TypeEnvironment&))87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&)) 90 90 conversionCost ); 91 91 src->accept( converter ); … … 98 98 } 99 99 100 Cost convertToReferenceCost( Type * src,Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {100 Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 101 101 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 102 102 if ( diff > 0 ) { 103 103 // TODO: document this 104 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );104 Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 105 105 cost.incReference(); 106 106 return cost; 107 107 } else if ( diff < -1 ) { 108 108 // TODO: document this 109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 110 110 cost.incReference(); 111 111 return cost; 112 112 } else if ( diff == 0 ) { 113 ReferenceType * srcAsRef = dynamic_cast<ReferenceType * >( src );114 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );113 const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src ); 114 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 115 115 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 116 116 PRINT( std::cerr << "converting between references" << std::endl; ) 117 Type::Qualifiers tq1 = srcAsRef->base-> get_qualifiers();118 Type::Qualifiers tq2 = destAsRef->base-> get_qualifiers();117 Type::Qualifiers tq1 = srcAsRef->base->tq; 118 Type::Qualifiers tq2 = destAsRef->base->tq; 119 119 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 120 120 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 137 137 } else { 138 138 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)( Type*,Type*, const SymTab::Indexer&, const TypeEnvironment&))139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&)) 142 142 conversionCost ); 143 143 src->accept( converter ); … … 145 145 } // if 146 146 } else { 147 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );147 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 148 148 assert( diff == -1 && destAsRef ); 149 149 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) … … 156 156 ) 157 157 // lvalue-to-reference conversion: cv lvalue T => cv T & 158 if ( src-> get_qualifiers() == destAsRef->base->get_qualifiers()) {158 if ( src->tq == destAsRef->base->tq ) { 159 159 return Cost::reference; // cost needs to be non-zero to add cast 160 } if ( src-> get_qualifiers() < destAsRef->base->get_qualifiers()) {160 } if ( src->tq < destAsRef->base->tq ) { 161 161 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 162 162 } else { … … 178 178 } 179 179 180 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {180 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 181 181 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 182 182 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); … … 185 185 } 186 186 187 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )187 ConversionCost::ConversionCost( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 188 188 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 189 189 } … … 193 193 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 194 194 _Bool 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 208 208 __float80 209 _Float128 _Float128 _Complex 209 _Float128 _Float128 _Complex 210 210 __float128 211 long double long double _Complex 212 _Float128x _Float128x _Complex 211 long double long double _Complex 212 _Float128x _Float128x _Complex 213 213 */ 214 214 // GENERATED END … … 309 309 ); 310 310 311 void ConversionCost::postvisit( VoidType * ) {311 void ConversionCost::postvisit( const VoidType * ) { 312 312 cost = Cost::infinity; 313 313 } 314 314 315 void ConversionCost::postvisit( BasicType *basicType) {316 if ( BasicType *destAsBasic = dynamic_cast<BasicType* >( dest ) ) {317 int tableResult = costMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()];315 void ConversionCost::postvisit(const BasicType *basicType) { 316 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) { 317 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 318 318 if ( tableResult == -1 ) { 319 319 cost = Cost::unsafe; … … 321 321 cost = Cost::zero; 322 322 cost.incSafe( tableResult ); 323 cost.incSign( signMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()] );324 } // if 325 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {323 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 324 } // if 325 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 326 326 // xxx - not positive this is correct, but appears to allow casting int => enum 327 327 cost = Cost::unsafe; … … 330 330 } 331 331 332 void ConversionCost::postvisit( PointerType * pointerType ) {333 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {332 void ConversionCost::postvisit( const PointerType * pointerType ) { 333 if ( const PointerType *destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 334 334 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 335 Type::Qualifiers tq1 = pointerType->base-> get_qualifiers();336 Type::Qualifiers tq2 = destAsPtr->base-> get_qualifiers();335 Type::Qualifiers tq1 = pointerType->base->tq; 336 Type::Qualifiers tq2 = destAsPtr->base->tq; 337 337 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 338 338 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 363 363 } 364 364 365 void ConversionCost::postvisit( ArrayType * ) {}366 367 void ConversionCost::postvisit( ReferenceType * refType ) {365 void ConversionCost::postvisit( const ArrayType * ) {} 366 367 void ConversionCost::postvisit( const ReferenceType * refType ) { 368 368 // Note: dest can never be a reference, since it would have been caught in an earlier check 369 assert( ! dynamic_cast< ReferenceType * >( dest ) );369 assert( ! dynamic_cast< const ReferenceType * >( dest ) ); 370 370 // convert reference to rvalue: cv T1 & => T2 371 371 // recursively compute conversion cost from T1 to T2. 372 372 // cv can be safely dropped because of 'implicit dereference' behavior. 373 373 cost = costFunc( refType->base, dest, indexer, env ); 374 if ( refType->base-> get_qualifiers() == dest->get_qualifiers()) {374 if ( refType->base->tq == dest->tq ) { 375 375 cost.incReference(); // prefer exact qualifiers 376 } else if ( refType->base-> get_qualifiers() < dest->get_qualifiers()) {376 } else if ( refType->base->tq < dest->tq ) { 377 377 cost.incSafe(); // then gaining qualifiers 378 378 } else { … … 382 382 } 383 383 384 void ConversionCost::postvisit( FunctionType * ) {}385 386 void ConversionCost::postvisit( StructInstType * inst ) {387 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {384 void ConversionCost::postvisit( const FunctionType * ) {} 385 386 void ConversionCost::postvisit( const StructInstType * inst ) { 387 if ( const StructInstType *destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 388 388 if ( inst->name == destAsInst->name ) { 389 389 cost = Cost::zero; … … 392 392 } 393 393 394 void ConversionCost::postvisit( UnionInstType * inst ) {395 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {394 void ConversionCost::postvisit( const UnionInstType * inst ) { 395 if ( const UnionInstType *destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 396 396 if ( inst->name == destAsInst->name ) { 397 397 cost = Cost::zero; … … 400 400 } 401 401 402 void ConversionCost::postvisit( EnumInstType * ) {402 void ConversionCost::postvisit( const EnumInstType * ) { 403 403 static Type::Qualifiers q; 404 404 static BasicType integer( q, BasicType::SignedInt ); … … 409 409 } 410 410 411 void ConversionCost::postvisit( TraitInstType * ) {}412 413 void ConversionCost::postvisit( TypeInstType *inst ) {411 void ConversionCost::postvisit( const TraitInstType * ) {} 412 413 void ConversionCost::postvisit( const TypeInstType *inst ) { 414 414 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) { 415 415 cost = costFunc( eqvClass->type, dest, indexer, env ); 416 } else if ( TypeInstType *destAsInst = dynamic_cast<TypeInstType* >( dest ) ) {416 } else if ( const TypeInstType *destAsInst = dynamic_cast< const TypeInstType* >( dest ) ) { 417 417 if ( inst->name == destAsInst->name ) { 418 418 cost = Cost::zero; 419 419 } 420 420 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) { 421 TypeDecl *type = dynamic_cast<TypeDecl* >( namedType );421 const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType ); 422 422 // all typedefs should be gone by this point 423 423 assert( type ); … … 428 428 } 429 429 430 void ConversionCost::postvisit( TupleType * tupleType ) {430 void ConversionCost::postvisit( const TupleType * tupleType ) { 431 431 Cost c = Cost::zero; 432 if ( TupleType * destAsTuple = dynamic_cast<TupleType * >( dest ) ) {432 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) { 433 433 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 434 434 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); … … 448 448 } 449 449 450 void ConversionCost::postvisit( VarArgsType * ) {451 if ( dynamic_cast< VarArgsType* >( dest ) ) {452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( ZeroType * ) {457 if ( dynamic_cast< ZeroType * >( dest ) ) {458 cost = Cost::zero; 459 } else if ( BasicType *destAsBasic = dynamic_cast<BasicType* >( dest ) ) {450 void ConversionCost::postvisit( const VarArgsType * ) { 451 if ( dynamic_cast< const VarArgsType* >( dest ) ) { 452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( const ZeroType * ) { 457 if ( dynamic_cast< const ZeroType * >( dest ) ) { 458 cost = Cost::zero; 459 } else if ( const BasicType *destAsBasic = dynamic_cast< const BasicType* >( dest ) ) { 460 460 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 462 462 if ( tableResult == -1 ) { 463 463 cost = Cost::unsafe; … … 465 465 cost = Cost::zero; 466 466 cost.incSafe( tableResult + 1 ); 467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );468 } // if 469 } else if ( dynamic_cast< PointerType* >( dest ) ) {467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 468 } // if 469 } else if ( dynamic_cast< const PointerType* >( dest ) ) { 470 470 cost = Cost::zero; 471 471 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation … … 473 473 } 474 474 475 void ConversionCost::postvisit( OneType * ) {476 if ( dynamic_cast< OneType * >( dest ) ) {477 cost = Cost::zero; 478 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {475 void ConversionCost::postvisit( const OneType * ) { 476 if ( dynamic_cast< const OneType * >( dest ) ) { 477 cost = Cost::zero; 478 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 479 479 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 481 481 if ( tableResult == -1 ) { 482 482 cost = Cost::unsafe; … … 484 484 cost = Cost::zero; 485 485 cost.incSafe( tableResult + 1 ); 486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 487 487 } // if 488 488 } // if -
src/ResolvExpr/ConversionCost.h
ree6dbae r7870799 33 33 class TypeEnvironment; 34 34 35 typedef std::function<Cost( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;35 typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 36 36 struct ConversionCost : public WithShortCircuiting { 37 37 public: 38 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );38 ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction ); 39 39 40 40 Cost get_cost() const { return cost; } 41 41 42 void previsit( BaseSyntaxNode * ) { visit_children = false; }42 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 43 43 44 void postvisit( VoidType * voidType );45 void postvisit( BasicType * basicType );46 void postvisit( PointerType * pointerType );47 void postvisit( ArrayType * arrayType );48 void postvisit( ReferenceType * refType );49 void postvisit( FunctionType * functionType );50 void postvisit( StructInstType * aggregateUseType );51 void postvisit( UnionInstType * aggregateUseType );52 void postvisit( EnumInstType * aggregateUseType );53 void postvisit( TraitInstType * aggregateUseType );54 void postvisit( TypeInstType * aggregateUseType );55 void postvisit( TupleType * tupleType );56 void postvisit( VarArgsType * varArgsType );57 void postvisit( ZeroType * zeroType );58 void postvisit( OneType * oneType );44 void postvisit( const VoidType * voidType ); 45 void postvisit( const BasicType * basicType ); 46 void postvisit( const PointerType * pointerType ); 47 void postvisit( const ArrayType * arrayType ); 48 void postvisit( const ReferenceType * refType ); 49 void postvisit( const FunctionType * functionType ); 50 void postvisit( const StructInstType * aggregateUseType ); 51 void postvisit( const UnionInstType * aggregateUseType ); 52 void postvisit( const EnumInstType * aggregateUseType ); 53 void postvisit( const TraitInstType * aggregateUseType ); 54 void postvisit( const TypeInstType * aggregateUseType ); 55 void postvisit( const TupleType * tupleType ); 56 void postvisit( const VarArgsType * varArgsType ); 57 void postvisit( const ZeroType * zeroType ); 58 void postvisit( const OneType * oneType ); 59 59 protected: 60 Type *dest;60 const Type * dest; 61 61 const SymTab::Indexer &indexer; 62 62 Cost cost; … … 65 65 }; 66 66 67 typedef std::function<int( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;68 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );67 typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction; 68 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ); 69 69 70 70 // Some function pointer types, differ in return type. -
src/ResolvExpr/PtrsAssignable.cc
ree6dbae r7870799 27 27 namespace ResolvExpr { 28 28 struct PtrsAssignable : public WithShortCircuiting { 29 PtrsAssignable( Type *dest, const TypeEnvironment &env );29 PtrsAssignable( const Type * dest, const TypeEnvironment &env ); 30 30 31 31 int get_result() const { return result; } 32 32 33 void previsit( Type * ) { visit_children = false; }34 35 void postvisit( VoidType * voidType );36 void postvisit( BasicType * basicType );37 void postvisit( PointerType * pointerType );38 void postvisit( ArrayType * arrayType );39 void postvisit( FunctionType * functionType );40 void postvisit( StructInstType * inst );41 void postvisit( UnionInstType * inst );42 void postvisit( EnumInstType * inst );43 void postvisit( TraitInstType * inst );44 void postvisit( TypeInstType * inst );45 void postvisit( TupleType * tupleType );46 void postvisit( VarArgsType * varArgsType );47 void postvisit( ZeroType * zeroType );48 void postvisit( OneType * oneType );33 void previsit( const Type * ) { visit_children = false; } 34 35 void postvisit( const VoidType * voidType ); 36 void postvisit( const BasicType * basicType ); 37 void postvisit( const PointerType * pointerType ); 38 void postvisit( const ArrayType * arrayType ); 39 void postvisit( const FunctionType * functionType ); 40 void postvisit( const StructInstType * inst ); 41 void postvisit( const UnionInstType * inst ); 42 void postvisit( const EnumInstType * inst ); 43 void postvisit( const TraitInstType * inst ); 44 void postvisit( const TypeInstType * inst ); 45 void postvisit( const TupleType * tupleType ); 46 void postvisit( const VarArgsType * varArgsType ); 47 void postvisit( const ZeroType * zeroType ); 48 void postvisit( const OneType * oneType ); 49 49 private: 50 Type *dest;50 const Type * dest; 51 51 int result; 52 52 const TypeEnvironment &env; 53 53 }; 54 54 55 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) { 56 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 57 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 59 59 return ptrsAssignable( src, eqvClass->type, env ); 60 60 } // if 61 61 } // if 62 if ( dynamic_cast< VoidType* >( dest ) ) {62 if ( dynamic_cast< const VoidType* >( dest ) ) { 63 63 // void * = T * for any T is unsafe 64 64 // xxx - this should be safe, but that currently breaks the build … … 71 71 } 72 72 73 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}74 75 void PtrsAssignable::postvisit( VoidType * ) {73 PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( const VoidType * ) { 76 76 // T * = void * is disallowed - this is a change from C, where any 77 77 // void * can be assigned or passed to a non-void pointer without a cast. 78 78 } 79 79 80 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType) {}82 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType) {}83 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType) {}84 85 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst) {}86 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst) {}87 88 void PtrsAssignable::postvisit( EnumInstType * ) {89 if ( dynamic_cast< BasicType* >( dest ) ) {80 void PtrsAssignable::postvisit( const BasicType * ) {} 81 void PtrsAssignable::postvisit( const PointerType * ) {} 82 void PtrsAssignable::postvisit( const ArrayType * ) {} 83 void PtrsAssignable::postvisit( const FunctionType * ) {} 84 85 void PtrsAssignable::postvisit( const StructInstType * ) {} 86 void PtrsAssignable::postvisit( const UnionInstType * ) {} 87 88 void PtrsAssignable::postvisit( const EnumInstType * ) { 89 if ( dynamic_cast< const BasicType* >( dest ) ) { 90 90 // int * = E *, etc. is safe. This isn't technically correct, as each 91 91 // enum has one basic type that it is compatible with, an that type can … … 97 97 } 98 98 99 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst) {}100 void PtrsAssignable::postvisit( TypeInstType *inst ) {101 if ( const EqvClass * eqvClass = env.lookup( inst->get_name()) ) {99 void PtrsAssignable::postvisit( const TraitInstType * ) {} 100 void PtrsAssignable::postvisit( const TypeInstType * inst ) { 101 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 102 102 if ( eqvClass->type ) { 103 103 // T * = S * for any S depends on the type bound to T … … 107 107 } 108 108 109 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType) {}110 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType) {}111 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType) {}112 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType) {}109 void PtrsAssignable::postvisit( const TupleType * ) {} 110 void PtrsAssignable::postvisit( const VarArgsType * ) {} 111 void PtrsAssignable::postvisit( const ZeroType * ) {} 112 void PtrsAssignable::postvisit( const OneType * ) {} 113 113 114 114 // TODO: Get rid of the `_new` suffix when the old version is removed. -
src/ResolvExpr/PtrsCastable.cc
ree6dbae r7870799 29 29 struct PtrsCastable_old : public WithShortCircuiting { 30 30 public: 31 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );31 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 32 32 33 33 int get_result() const { return result; } 34 34 35 void previsit( Type * ) { visit_children = false; }36 37 void postvisit( VoidType * voidType );38 void postvisit( BasicType * basicType );39 void postvisit( PointerType * pointerType );40 void postvisit( ArrayType * arrayType );41 void postvisit( FunctionType * functionType );42 void postvisit( StructInstType * inst );43 void postvisit( UnionInstType * inst );44 void postvisit( EnumInstType * inst );45 void postvisit( TraitInstType * inst );46 void postvisit( TypeInstType * inst );47 void postvisit( TupleType * tupleType );48 void postvisit( VarArgsType * varArgsType );49 void postvisit( ZeroType * zeroType );50 void postvisit( OneType * oneType );35 void previsit( const Type * ) { visit_children = false; } 36 37 void postvisit( const VoidType * voidType ); 38 void postvisit( const BasicType * basicType ); 39 void postvisit( const PointerType * pointerType ); 40 void postvisit( const ArrayType * arrayType ); 41 void postvisit( const FunctionType * functionType ); 42 void postvisit( const StructInstType * inst ); 43 void postvisit( const UnionInstType * inst ); 44 void postvisit( const EnumInstType * inst ); 45 void postvisit( const TraitInstType * inst ); 46 void postvisit( const TypeInstType * inst ); 47 void postvisit( const TupleType * tupleType ); 48 void postvisit( const VarArgsType * varArgsType ); 49 void postvisit( const ZeroType * zeroType ); 50 void postvisit( const OneType * oneType ); 51 51 private: 52 Type *dest;52 const Type * dest; 53 53 int result; 54 54 const TypeEnvironment &env; … … 57 57 58 58 namespace { 59 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {60 if ( dynamic_cast< FunctionType* >( src ) ) {59 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 60 if ( dynamic_cast< const FunctionType* >( src ) ) { 61 61 return -1; 62 } else if ( TypeInstType *typeInst = dynamic_cast<TypeInstType* >( src ) ) {63 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name()) ) {64 if ( TypeDecl *tyDecl = dynamic_cast<TypeDecl* >( ntDecl ) ) {65 if ( tyDecl-> get_kind()== TypeDecl::Ftype ) {62 } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) { 63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) { 64 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) { 65 if ( tyDecl->kind == TypeDecl::Ftype ) { 66 66 return -1; 67 67 } // if 68 68 } //if 69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 70 70 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 71 71 return -1; … … 75 75 return 1; 76 76 } 77 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {77 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 78 78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast 79 79 } 80 80 } 81 81 82 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {83 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {82 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 85 85 // xxx - should this be ptrsCastable? 86 86 return ptrsAssignable( src, eqvClass->type, env ); 87 87 } // if 88 88 } // if 89 if ( dynamic_cast< VoidType* >( dest ) ) {89 if ( dynamic_cast< const VoidType* >( dest ) ) { 90 90 return objectCast( src, env, indexer ); 91 91 } else { … … 96 96 } 97 97 98 PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )98 PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) 99 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 100 100 } 101 101 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 * ) {102 void PtrsCastable_old::postvisit( const VoidType * ) { 103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( const BasicType * ) { 107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( const PointerType * ) { 111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( const ArrayType * ) { 115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( const FunctionType * ) { 119 119 // result = -1; 120 120 result = functionCast( dest, env, indexer ); 121 121 } 122 122 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 * ) {132 if ( dynamic_cast< EnumInstType* >( dest ) ) {123 void PtrsCastable_old::postvisit( const StructInstType * ) { 124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( const UnionInstType * ) { 128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( const EnumInstType * ) { 132 if ( dynamic_cast< const EnumInstType * >( dest ) ) { 133 133 result = 1; 134 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {135 if ( bt-> get_kind()== BasicType::SignedInt ) {134 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) { 135 if ( bt->kind == BasicType::SignedInt ) { 136 136 result = 0; 137 137 } else { … … 143 143 } 144 144 145 void PtrsCastable_old::postvisit( TraitInstType * ) {}146 147 void PtrsCastable_old::postvisit( TypeInstType *inst ) {145 void PtrsCastable_old::postvisit( const TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit( const TypeInstType *inst ) { 148 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 149 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 150 150 } 151 151 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 * ) {152 void PtrsCastable_old::postvisit( const TupleType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( const VarArgsType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( const ZeroType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( const OneType * ) { 165 165 result = objectCast( dest, env, indexer ); 166 166 } … … 168 168 namespace { 169 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 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 172 172 ) { 173 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { … … 191 191 192 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 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 195 195 ) { 196 196 return -1 * objectCast( src, env, symtab ); … … 204 204 int result; 205 205 206 PtrsCastable_new( 206 PtrsCastable_new( 207 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} … … 278 278 } // anonymous namespace 279 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 283 ) { 284 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { -
src/ResolvExpr/Unify.cc
ree6dbae r7870799 97 97 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 98 98 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 102 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 103 … … 121 121 } 122 122 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 125 125 const ast::TypeEnvironment & env ) { 126 126 ast::TypeEnvironment newEnv; … … 135 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 136 137 return unifyExact( 137 return unifyExact( 138 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 139 } 140 140 141 bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {141 bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 142 142 TypeEnvironment newEnv; 143 143 OpenVarSet openVars; … … 163 163 } 164 164 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 167 167 const ast::TypeEnvironment & env ) { 168 168 ast::TypeEnvironment newEnv; 169 169 ast::OpenVarSet open; 170 170 ast::AssertionSet need, have; 171 171 172 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 173 env.apply( newFirst ); … … 176 176 reset_qualifiers( newSecond ); 177 177 178 return unifyExact( 178 return unifyExact( 179 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 180 180 } … … 490 490 491 491 // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 497 497 ) { 498 498 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { … … 711 711 bool result; 712 712 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 716 716 const ast::SymbolTable & symtab ) 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 718 718 symtab(symtab), result(false) {} 719 719 720 720 void previsit( const ast::Node * ) { visit_children = false; } 721 721 722 722 void postvisit( const ast::VoidType * ) { 723 723 result = dynamic_cast< const ast::VoidType * >( type2 ); … … 732 732 void postvisit( const ast::PointerType * pointer ) { 733 733 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 736 736 noWiden(), symtab ); 737 737 } … … 742 742 if ( ! array2 ) return; 743 743 744 // to unify, array types must both be VLA or both not VLA and both must have a 744 // to unify, array types must both be VLA or both not VLA and both must have a 745 745 // dimension expression or not have a dimension 746 746 if ( array->isVarLen != array2->isVarLen ) return; 747 if ( ! array->isVarLen && ! array2->isVarLen 747 if ( ! array->isVarLen && ! array2->isVarLen 748 748 && array->dimension && array2->dimension ) { 749 749 auto ce1 = array->dimension.as< ast::ConstantExpr >(); … … 751 751 752 752 // see C11 Reference Manual 6.7.6.2.6 753 // two array types with size specifiers that are integer constant expressions are 753 // two array types with size specifiers that are integer constant expressions are 754 754 // compatible if both size specifiers have the same constant value 755 755 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return; 756 756 } 757 757 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 760 760 symtab ); 761 761 } … … 763 763 void postvisit( const ast::ReferenceType * ref ) { 764 764 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 767 767 symtab ); 768 768 } … … 771 771 private: 772 772 /// Replaces ttype variables with their bound types. 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 774 774 /// different size and structure when they should be compatible. 775 775 struct TtypeExpander_new : public ast::WithShortCircuiting { … … 800 800 auto types = flatten( d->get_type() ); 801 801 for ( ast::ptr< ast::Type > & t : types ) { 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 804 804 // whether a function is callable. 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 807 807 // requirements than a non-mutex function 808 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); … … 818 818 std::vector< ast::ptr< ast::Type > > types; 819 819 while ( crnt != end ) { 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 821 821 // that this results in a flat tuple 822 822 flatten( (*crnt)->get_type(), types ); … … 829 829 830 830 template< typename Iter > 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 834 834 const ast::SymbolTable & symtab 835 835 ) { … … 843 843 if ( isTuple1 && ! isTuple2 ) { 844 844 // combine remainder of list2, then unify 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 847 847 noWiden(), symtab ); 848 848 } else if ( ! isTuple1 && isTuple2 ) { 849 849 // combine remainder of list1, then unify 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 852 852 noWiden(), symtab ); 853 853 } 854 854 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 857 857 ) return false; 858 858 … … 860 860 } 861 861 862 // May get to the end of one argument list before the other. This is only okay if the 862 // May get to the end of one argument list before the other. This is only okay if the 863 863 // other is a ttype 864 864 if ( crnt1 != end1 ) { … … 866 866 const ast::Type * t1 = (*crnt1)->get_type(); 867 867 if ( ! Tuples::isTtype( t1 ) ) return false; 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 870 870 noWiden(), symtab ); 871 871 } else if ( crnt2 != end2 ) { … … 873 873 const ast::Type * t2 = (*crnt2)->get_type(); 874 874 if ( ! Tuples::isTtype( t2 ) ) return false; 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 877 877 noWiden(), symtab ); 878 878 } … … 881 881 } 882 882 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 887 887 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 888 888 ) { 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 891 891 symtab ); 892 892 } … … 900 900 901 901 /// mark all assertions in `type` used in both `assn1` and `assn2` 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 905 905 ) { 906 906 for ( const auto & tyvar : type->forall ) { … … 918 918 919 919 if ( func->isVarArgs != func2->isVarArgs ) return; 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 922 922 // affect unification. Does not actually mutate function parameters. 923 923 auto params = flattenList( func->params, tenv ); 924 924 auto params2 = flattenList( func2->params, tenv ); 925 925 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 927 927 // where the ttype is to prevent errors 928 if ( 928 if ( 929 929 ( params.size() != params2.size() || func->returns.size() != func2->returns.size() ) 930 930 && ! func->isTtype() … … 933 933 934 934 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 935 if ( ! unifyDeclList( 935 if ( ! unifyDeclList( 936 936 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 937 937 938 938 markAssertions( have, need, func ); 939 939 markAssertions( have, need, func2 ); … … 941 941 result = true; 942 942 } 943 943 944 944 private: 945 945 template< typename RefType > … … 953 953 /// Creates a tuple type based on a list of TypeExpr 954 954 template< typename Iter > 955 static const ast::Type * tupleFromExprs( 955 static const ast::Type * tupleFromExprs( 956 956 const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs 957 957 ) { … … 973 973 const RefType * inst2 = handleRefType( inst, other ); 974 974 if ( ! inst2 ) return; 975 975 976 976 // check that parameters of types unify, if any 977 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; … … 1002 1002 } 1003 1003 1004 if ( ! unifyExact( 1004 if ( ! unifyExact( 1005 1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1006 1006 result = false; … … 1038 1038 private: 1039 1039 /// Creates a tuple type based on a list of Type 1040 static ast::ptr< ast::Type > tupleFromTypes( 1040 static ast::ptr< ast::Type > tupleFromTypes( 1041 1041 const std::vector< ast::ptr< ast::Type > > & tys 1042 1042 ) { 1043 1043 std::vector< ast::ptr< ast::Type > > out; 1044 1044 for ( const ast::Type * ty : tys ) { 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1046 1046 // that this results in a flat tuple 1047 1047 flatten( ty, out ); … … 1051 1051 } 1052 1052 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1057 1057 const ast::SymbolTable & symtab 1058 1058 ) { … … 1068 1068 if ( isTuple1 && ! isTuple2 ) { 1069 1069 // combine entirety of list2, then unify 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1072 1072 noWiden(), symtab ); 1073 1073 } else if ( ! isTuple1 && isTuple2 ) { 1074 1074 // combine entirety of list1, then unify 1075 1075 return unifyExact( 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1077 1077 noWiden(), symtab ); 1078 1078 } 1079 1079 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1082 1082 ) return false; 1083 1083 … … 1089 1089 const ast::Type * t1 = *crnt1; 1090 1090 if ( ! Tuples::isTtype( t1 ) ) return false; 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1092 1092 // from Rob's code 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1095 1095 noWiden(), symtab ); 1096 1096 } else if ( crnt2 != list2.end() ) { … … 1098 1098 const ast::Type * t2 = *crnt2; 1099 1099 if ( ! Tuples::isTtype( t2 ) ) return false; 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1101 1101 // from Rob's code 1102 1102 return unifyExact( 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1104 1104 noWiden(), symtab ); 1105 1105 } … … 1133 1133 void postvisit( const ast::OneType * ) { 1134 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1135 } 1135 } 1136 1136 1137 1137 private: … … 1140 1140 }; 1141 1141 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1145 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1146 1146 ) { … … 1149 1149 } 1150 1150 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1155 1155 ) { 1156 1156 ast::OpenVarSet closed; 1157 1157 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1158 1158 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1159 return unifyInexact( 1159 return unifyInexact( 1160 1160 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1161 1161 } 1162 1162 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1166 1166 WidenMode widen, const ast::SymbolTable & symtab 1167 1167 ) { … … 1170 1170 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1171 1171 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1174 1174 entry2 = var2 ? open.find( var2->name ) : open.end(); 1175 1175 bool isopen1 = entry1 != open.end(); … … 1178 1178 if ( isopen1 && isopen2 ) { 1179 1179 if ( entry1->second.kind != entry2->second.kind ) return false; 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1182 1182 open, widen, symtab ); 1183 1183 } else if ( isopen1 ) { … … 1192 1192 } 1193 1193 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1199 1199 ) { 1200 1200 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1203 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 1205 reset_qualifiers( t1 ); 1206 1206 reset_qualifiers( t2 ); 1207 1207 1208 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones -
src/ResolvExpr/typeops.h
ree6dbae r7870799 73 73 74 74 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 75 const ast::Type * adjustExprType( 75 const ast::Type * adjustExprType( 76 76 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 77 77 78 78 // in CastCost.cc 79 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );80 Cost castCost( 81 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 79 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 80 Cost castCost( 81 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 82 82 const ast::TypeEnvironment & env ); 83 83 84 84 // in ConversionCost.cc 85 Cost conversionCost( Type *src,Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 85 Cost conversionCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 88 88 const ast::TypeEnvironment & env ); 89 89 90 90 // in AlternativeFinder.cc 91 Cost computeConversionCost( Type *actualType, Type *formalType, 91 Cost computeConversionCost( Type *actualType, Type *formalType, 92 92 const SymTab::Indexer &indexer, const TypeEnvironment &env ); 93 93 94 94 // in PtrsAssignable.cc 95 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );95 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment &env ); 96 96 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 97 97 const ast::TypeEnvironment & env ); 98 98 99 99 // in PtrsCastable.cc 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, 100 int ptrsCastable( const Type * src, const 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 103 const ast::TypeEnvironment & env ); 104 104 105 105 // in Unify.cc 106 106 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 107 bool typesCompatibleIgnoreQualifiers( Type *,Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );107 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 108 108 109 109 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) { … … 112 112 } 113 113 114 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {114 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer &indexer ) { 115 115 TypeEnvironment env; 116 116 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 117 117 } 118 118 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 121 121 const ast::TypeEnvironment & env = {} ); 122 122 123 123 bool typesCompatibleIgnoreQualifiers( 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 125 125 const ast::TypeEnvironment & env = {} ); 126 126 … … 133 133 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 134 134 ast::ptr< ast::Type > commonType( 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 136 136 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 137 137 138 138 // in PolyCost.cc 139 139 int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 140 int polyCost( 140 int polyCost( 141 141 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 142 142 … … 149 149 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 150 150 151 template<typename Iter> 151 template<typename Iter> 152 152 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) { 153 153 while ( begin != end ) { … … 176 176 177 177 /// flatten tuple type into existing list of types 178 static inline void flatten( 179 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 178 static inline void flatten( 179 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 180 180 ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 182 182 for ( const ast::Type * t : tupleType->types ) { 183 183 flatten( t, out );
Note:
See TracChangeset
for help on using the changeset viewer.