Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cpp

    rc92bdcc r85855b0  
    191191}
    192192
     193Cost enumCastCost (
     194        const ast::EnumInstType * src, const ast::EnumInstType * dst,
     195        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     196);
     197
    193198static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    194199                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
     
    279284        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    280285                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    281         } else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) {
    282                 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    283                 cost = costCalc( basicType, integer, srcIsLvalue, symtab, env );
    284         } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     286        }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    285287                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    286288                        cost = Cost::unsafe;
     
    362364
    363365void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
    364         if ( auto dstAsInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    365                 if (inst->base && dstAsInst->base) {
    366                         if (inst->base->name == dstAsInst->base->name) {
    367                                 cost = Cost::zero;
    368                                 return;
    369                         }
    370                 }
     366        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
     367                cost = enumCastCost(inst, dstInst, symtab, env);
    371368                return;
    372369        }
    373370        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    374371        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    375         if ( cost < Cost::unsafe ) {
    376                 cost.incSafe();
    377         }
    378 }
    379 
    380 void ConversionCost::postvisit( const ast::EnumAttrType * src ) {
    381         auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
    382         assert( src->attr != ast::EnumAttribute::Label );
    383         if ( src->attr == ast::EnumAttribute::Value ) {
    384                 if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
    385                         cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
    386                 } else {
    387                         auto baseType = src->instance->base->base;
    388                         cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
    389                         if ( cost < Cost::infinity ) {
    390                                 cost.incUnsafe();
    391                         }
    392                 }
    393         } else { // ast::EnumAttribute::Posn
    394                 if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    395                         cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
    396                         if ( cost < Cost::unsafe ) cost.incSafe();
    397                 } else {
    398                         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    399                         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    400                         if ( cost < Cost::unsafe ) {
    401                                 cost.incSafe();
    402                         }
    403                 }
    404         }
     372        if ( !inst->base->isTyped ) {
     373                if ( cost < Cost::unsafe ) {
     374                        cost.incSafe();
     375                }
     376                return;
     377        }
     378        cost.incUnsafe();
    405379}
    406380
     
    507481}
    508482
     483// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
     484Cost enumCastCost (
     485        const ast::EnumInstType * src, const ast::EnumInstType * dst,
     486        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     487) {
     488        auto srcDecl = src->base;
     489        auto dstDecl = dst->base;
     490        if (srcDecl->name == dstDecl->name) return Cost::safe;
     491        Cost minCost = Cost::infinity;
     492        for (auto child: dstDecl->inlinedDecl) {
     493                Cost c = enumCastCost(src, child, symtab, env) + Cost::safe;
     494                if (c<minCost) minCost = c;
     495        }
     496        return minCost;
     497}
     498
     499
    509500// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
    510501
Note: See TracChangeset for help on using the changeset viewer.