Changes in / [3c55fcd:4117761]


Ignore:
Location:
src
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

    r3c55fcd r4117761  
    203203}
    204204
     205bool EnumDecl::isTyped() const { return base;}
     206
     207bool EnumDecl::isOpague() const { return isCfa && !isTyped(); }
    205208}
    206209
  • src/AST/Decl.hpp

    r3c55fcd r4117761  
    308308class EnumDecl final : public AggregateDecl {
    309309public:
    310         // isTyped indicated if the enum has a declaration like:
     310        // isCfa indicated if the enum has a declaration like:
    311311        // enum (type_optional) Name {...}
    312         bool isTyped;
    313         // if isTyped == true && base.get() == nullptr, it is a "void" type enum
     312        bool isCfa;
     313        // if isCfa == true && base.get() == nullptr, it is a "opague" enum
    314314        ptr<Type> base;
    315315        enum class EnumHiding { Visible, Hide } hide;
    316316        std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
    317317
    318         EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
     318        EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
    319319                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
    320320                Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
    321321                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
    322         : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
     322        : AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
    323323
    324324        /// gets the integer value for this enumerator, returning true iff value found
     
    336336
    337337        bool isSubTypeOf(const ast::EnumDecl *) const;
     338        bool isTyped() const;
     339        bool isOpague() const;
    338340private:
    339341        EnumDecl * clone() const override { return new EnumDecl{ *this }; }
  • src/AST/Stmt.hpp

    r3c55fcd r4117761  
    238238        ptr<Expr> inc;
    239239        ptr<Expr> range_over;
     240        bool is_inc;
    240241        ptr<Stmt> body;
    241242        ptr<Stmt> else_;
     
    251252                        range_over(nullptr), body(body), else_(else_) {}
    252253
    253         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
     254        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
    254255                         const Stmt * body, const Stmt * else_ )
    255                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
     256                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
     257                body(body), else_(else_) {}
    256258
    257259        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/ControlStruct/TranslateEnumRange.cpp

    r3c55fcd r4117761  
    2626        auto enumDecl = enumInst->base;
    2727
    28         auto init = stmt->inits.front();
     28        auto objInit = stmt->inits.front();
    2929
    30         if (auto declStmt = init.as<ast::DeclStmt>()) {
     30        auto initLocation = objInit->location;
     31        auto rangeLocation = stmt->range_over->location;
     32        assert( stmt->inits.size() == 1 );
     33
     34        if (auto declStmt = objInit.as<ast::DeclStmt>()) {
    3135            auto decl = declStmt->decl;
    3236            if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
     
    5761                if ( !objDecl->init ) {
    5862                    auto location = stmt->location;
    59                     auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
     63                    ast::SingleInit * newInit;
     64                    newInit = new ast::SingleInit( location,
     65                        new ast::NameExpr( location,
     66                        stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
    6067                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6168                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    7885    auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    7986    auto enumDecl = enumInst->base;
     87   
     88    // Both inc and dec check if the current posn less than the number of enumerator
     89    // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
     90    // it wraps around and become unsigned max
     91    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
     92        "?<=?",
     93        {new ast::CastExpr(location,
     94            new ast::NameExpr( location, indexName ),
     95            new ast::BasicType( ast::BasicKind::UnsignedInt ),
     96            ast::GeneratedFlag::ExplicitCast),
     97        ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 ) });
    8098
    81     auto condition = ast::UntypedExpr::createCall( location, "?<=?", {
    82         new ast::NameExpr( location, indexName ),
    83         // ast::ConstantExpr::from_ulong( location, enumDecl->members.size() )
    84         new ast::NameExpr( location, enumDecl->members.back()->name )
    85     });
    86     auto increment = ast::UntypedExpr::createCall( location, "succ", {
    87         new ast::NameExpr( location, indexName )
    88     });
     99    auto increment = ast::UntypedExpr::createCall( location,
     100        stmt->is_inc? "?++": "?--",
     101        { new ast::NameExpr( location, indexName ) });
     102   
    89103    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    90104    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • src/Parser/StatementNode.cpp

    r3c55fcd r4117761  
    216216                return new ast::ForStmt( location,
    217217                        std::move( astinit ),
    218                         range_over,
     218                        range_over, forctl->kind == OperKinds::LThan,
    219219                        buildMoveSingle( stmt ),
    220220                        buildMoveOptional( else_ )
  • src/Parser/StatementNode.hpp

    r3c55fcd r4117761  
    6464        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    6565                init( stmt ), condition( condition ), change( change ), range_over( nullptr ) {}
    66         ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
    67                 init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
    6868
    6969        StatementNode * init;
     
    7171        ExpressionNode * change;
    7272        ExpressionNode * range_over;
     73        OperKinds kind;
    7374};
    7475
  • src/Parser/TypeData.cpp

    r3c55fcd r4117761  
    14691469                ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
    14701470                object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
    1471                 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
    1472                         SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
     1471                if ( ret->isOpague() && cur->has_enumeratorValue() ) {
     1472                        SemanticError( td->location, "Opague cannot have an explicit initializer value." );
    14731473                } else if ( cur->has_enumeratorValue() ) {
    14741474                        object->init = new ast::SingleInit(
  • src/Parser/parser.yy

    r3c55fcd r4117761  
    279279                DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
    280280                assert( range_over_expr );
    281                 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
     281                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
    282282        } else {
    283283                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
  • src/ResolvExpr/CandidateFinder.cpp

    r3c55fcd r4117761  
    698698                void postvisit( const ast::CountExpr * countExpr );
    699699
    700                 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,
    701                         const ast::EnumInstType * dst
    702                         , const ast::Expr * expr, Cost minCost );
    703 
    704700                void postvisit( const ast::InitExpr * ) {
    705701                        assertf( false, "CandidateFinder should never see a resolved InitExpr." );
     
    12131209        }
    12141210
    1215         // src is a subset of dst
    1216         const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src,
    1217                 const ast::EnumInstType * dst,
    1218                 const ast::Expr * expr,
    1219                 Cost minCost ) {
    1220                
    1221                 auto srcDecl = src->base;
    1222                 auto dstDecl = dst->base;
    1223 
    1224                 if (srcDecl->name == dstDecl->name) return expr;
    1225 
    1226                 for (auto& dstChild: dstDecl->inlinedDecl) {
    1227                         Cost c = castCost(src, dstChild, false, symtab, tenv);
    1228                         ast::CastExpr * castToDst;
    1229                         if (c<minCost) {
    1230                                 unsigned offset = dstDecl->calChildOffset(dstChild.get());
    1231                                 if (offset > 0) {
    1232                                         auto untyped = ast::UntypedExpr::createCall(
    1233                                                 expr->location,
    1234                                                 "?+?",
    1235                                                 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    1236                                                 ast::ConstantExpr::from_int(expr->location, offset)});
    1237                                         CandidateFinder finder(context, tenv);
    1238                                         finder.find( untyped );
    1239                                         CandidateList winners = findMinCost( finder.candidates );
    1240                                         CandidateRef & choice = winners.front();
    1241                                         // choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    1242                                         choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
    1243                                         // castToDst = new ast::CastExpr(choice->expr, dstChild);
    1244                                         castToDst = new ast::CastExpr(
    1245                                                 makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
    1246                                          dst);
    1247 
    1248                                 } else {
    1249                                         castToDst = new ast::CastExpr( expr, dst );
    1250                                 }
    1251                                 return castToDst;
    1252                         }
    1253                 }
    1254                 SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
    1255                 return nullptr;
    1256         }
    1257 
    12581211        void Finder::postvisit( const ast::CastExpr * castExpr ) {
    12591212                ast::ptr< ast::Type > toType = castExpr->result;
     
    13091262                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    13101263                        auto toAsEnum = toType.as<ast::EnumInstType>();
    1311                         if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {     
    1312                                 ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
     1264                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
     1265                                CandidateFinder subFinder(context, tenv);
     1266                                ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
    13131267                                cand->expr = offsetExpr;
    13141268                        }
     
    21932147                                        expr->location,
    21942148                                        "?+?",
    2195                                         { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    2196                                         ast::ConstantExpr::from_int(expr->location, offset)});
     2149                                        { new ast::CastExpr( expr->location,
     2150                                                expr,
     2151                                                new ast::BasicType(ast::BasicKind::SignedInt),
     2152                                                ast::GeneratedFlag::ExplicitCast ),
     2153                                                ast::ConstantExpr::from_int(expr->location, offset)} );
    21972154                                CandidateFinder finder(context, env);
    21982155                                finder.find( untyped );
  • src/ResolvExpr/CastCost.cpp

    r3c55fcd r4117761  
    5353                void postvisit( const ast::EnumInstType * enumInst ) {
    5454                        cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
     55
     56                        if ( !enumInst->base->isCfa ) {
     57                                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     58                                Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     59                                cost = intCost < cost? intCost: cost;
     60                        } else if ( enumInst->base->isTyped() ) {
     61                                auto baseConversionCost =
     62                                        castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
     63                                cost = baseConversionCost < cost? baseConversionCost: cost;
     64                        }
    5565                }
    5666
     
    6373                                cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
    6474                                if ( Cost::unsafe < cost ) {
    65                                         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    66                                                 // Always explict cast only for typed enum
    67                                                 if (enumInst->base->isTyped) cost = Cost::unsafe;
     75                                        if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     76                                                cost = Cost::unsafe;
    6877                                        }
    6978                                }
     
    7483                        cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
    7584                        if ( Cost::unsafe < cost ) {
    76                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    77                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     85                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     86                                        cost = Cost::unsafe;
    7887                                }
    7988                        }
     
    8392                        cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
    8493                        if ( Cost::unsafe < cost ) {
    85                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    86                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     94                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     95                                        cost = Cost::unsafe;
    8796                                }
    8897                        }
  • src/ResolvExpr/CommonType.cpp

    r3c55fcd r4117761  
    386386                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    387387                        const ast::EnumDecl* enumDecl = enumInst->base;
    388                         if ( !enumDecl->base ) {
     388                        if ( !enumDecl->isCfa ) {
    389389                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    390390                                if (
     
    642642                        const ast::EnumDecl* argDecl = argAsEnumInst->base;
    643643                        if (argDecl->isSubTypeOf(paramDecl)) result = param;
    644                 } else if ( param->base && !param->base->isTyped ) {
     644                } else if ( param->base && !param->base->isCfa ) {
    645645                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
    646646                        result = commonType( basicType, type2, tenv, need, have, open, widen);
  • src/ResolvExpr/ConversionCost.cpp

    r3c55fcd r4117761  
    162162Cost conversionCost(
    163163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    164         const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     164const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
    165165) {
    166166        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    235235                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
    236236                }
     237                if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
     238                        if (srcAsInst->base && !srcAsInst->base->isCfa) {
     239                                static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
     240                                return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
     241                        }
     242                }
    237243        } else {
    238244                assert( -1 == diff );
    239245                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    240246                assert( dstAsRef );
    241                 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
     247                auto dstBaseType = dstAsRef->base;
     248                const ast::Type * newSrc = src;
     249                if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
     250                        newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
     251                }
     252                if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
    242253                        if ( srcIsLvalue ) {
    243254                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
     
    284295        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    285296                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    286         }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    287                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    288                         cost = Cost::unsafe;
     297        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     298                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     299                        cost = Cost::safe;
    289300                }
    290301        }
     
    366377        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    367378                cost = enumCastCost(inst, dstInst, symtab, env);
    368                 return;
    369         }
    370         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    371         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    372         if ( !inst->base->isTyped ) {
    373                 if ( cost < Cost::unsafe ) {
    374                         cost.incSafe();
    375                 }
    376                 return;
    377         }
    378         cost.incUnsafe();
     379        } else if ( !inst->base->isCfa ) {
     380                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     381                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     382        }
     383        // cost.incUnsafe();
    379384}
    380385
     
    454459                // assuming 0p is supposed to be used for pointers?
    455460        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    456                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    457                         cost = Cost::unsafe;
     461                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     462                        cost = Cost::safe;
    458463                }
    459464        }
     
    475480                }
    476481        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    477                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    478                         cost = Cost::unsafe;
     482                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     483                        cost = Cost::safe;
    479484                }
    480485        }
  • src/ResolvExpr/Unify.cpp

    r3c55fcd r4117761  
    276276        void postvisit( const ast::VoidType * ) {
    277277                result = dynamic_cast< const ast::VoidType * >( type2 );
    278                         // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
    279                 ;
    280278        }
    281279
     
    284282                        result = basic->kind == basic2->kind;
    285283                }
    286                 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    287284        }
    288285
     
    293290                                noWiden());
    294291                }
    295                 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    296292        }
    297293
     
    312308                result = unifyExact(
    313309                        array->base, array2->base, tenv, need, have, open, noWiden());
    314                         // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    315310        }
    316311
     
    607602
    608603                result = unifyList( types, types2, tenv, need, have, open );
    609                         // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    610604        }
    611605
    612606        void postvisit( const ast::VarArgsType * ) {
    613607                result = dynamic_cast< const ast::VarArgsType * >( type2 );
    614                         // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    615608        }
    616609
    617610        void postvisit( const ast::ZeroType * ) {
    618611                result = dynamic_cast< const ast::ZeroType * >( type2 );
    619                         // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    620612        }
    621613
    622614        void postvisit( const ast::OneType * ) {
    623615                result = dynamic_cast< const ast::OneType * >( type2 );
    624                         // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    625616        }
    626617};
  • src/Validate/ImplementEnumFunc.cpp

    r3c55fcd r4117761  
    476476
    477477void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
    478         if (!enumDecl->body || !enumDecl->isTyped) return;
     478        if (!enumDecl->body || !enumDecl->isCfa) return;
    479479        ast::EnumInstType enumInst(enumDecl->name);
    480480        enumInst.base = enumDecl;
Note: See TracChangeset for help on using the changeset viewer.