Changes in / [4117761:3c55fcd]


Ignore:
Location:
src
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

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

    r4117761 r3c55fcd  
    308308class EnumDecl final : public AggregateDecl {
    309309public:
    310         // isCfa indicated if the enum has a declaration like:
     310        // isTyped indicated if the enum has a declaration like:
    311311        // enum (type_optional) Name {...}
    312         bool isCfa;
    313         // if isCfa == true && base.get() == nullptr, it is a "opague" enum
     312        bool isTyped;
     313        // if isTyped == true && base.get() == nullptr, it is a "void" type 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 isCfa = false,
     318        EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = 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 ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
     322        : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), 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;
    340338private:
    341339        EnumDecl * clone() const override { return new EnumDecl{ *this }; }
  • src/AST/Stmt.hpp

    r4117761 r3c55fcd  
    238238        ptr<Expr> inc;
    239239        ptr<Expr> range_over;
    240         bool is_inc;
    241240        ptr<Stmt> body;
    242241        ptr<Stmt> else_;
     
    252251                        range_over(nullptr), body(body), else_(else_) {}
    253252
    254         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
     253        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
    255254                         const Stmt * body, const Stmt * else_ )
    256                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
    257                 body(body), else_(else_) {}
     255                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
    258256
    259257        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/ControlStruct/TranslateEnumRange.cpp

    r4117761 r3c55fcd  
    2626        auto enumDecl = enumInst->base;
    2727
    28         auto objInit = stmt->inits.front();
     28        auto init = stmt->inits.front();
    2929
    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>()) {
     30        if (auto declStmt = init.as<ast::DeclStmt>()) {
    3531            auto decl = declStmt->decl;
    3632            if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
     
    6157                if ( !objDecl->init ) {
    6258                    auto location = stmt->location;
    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 ) );
     59                    auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
    6760                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6861                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    8578    auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    8679    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 ) });
    9880
    99     auto increment = ast::UntypedExpr::createCall( location,
    100         stmt->is_inc? "?++": "?--",
    101         { new ast::NameExpr( location, indexName ) });
    102    
     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    });
    10389    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    10490    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • src/Parser/StatementNode.cpp

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

    r4117761 r3c55fcd  
    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, OperKinds kind ) :
    67                 init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
    6868
    6969        StatementNode * init;
     
    7171        ExpressionNode * change;
    7272        ExpressionNode * range_over;
    73         OperKinds kind;
    7473};
    7574
  • src/Parser/TypeData.cpp

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

    r4117761 r3c55fcd  
    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, compop );
     281                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
    282282        } else {
    283283                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
  • src/ResolvExpr/CandidateFinder.cpp

    r4117761 r3c55fcd  
    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
    700704                void postvisit( const ast::InitExpr * ) {
    701705                        assertf( false, "CandidateFinder should never see a resolved InitExpr." );
     
    12091213        }
    12101214
     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
    12111258        void Finder::postvisit( const ast::CastExpr * castExpr ) {
    12121259                ast::ptr< ast::Type > toType = castExpr->result;
     
    12621309                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    12631310                        auto toAsEnum = toType.as<ast::EnumInstType>();
    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);
     1311                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {     
     1312                                ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
    12671313                                cand->expr = offsetExpr;
    12681314                        }
     
    21472193                                        expr->location,
    21482194                                        "?+?",
    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)} );
     2195                                        { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
     2196                                        ast::ConstantExpr::from_int(expr->location, offset)});
    21542197                                CandidateFinder finder(context, env);
    21552198                                finder.find( untyped );
  • src/ResolvExpr/CastCost.cpp

    r4117761 r3c55fcd  
    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                         }
    6555                }
    6656
     
    7363                                cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
    7464                                if ( Cost::unsafe < cost ) {
    75                                         if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    76                                                 cost = Cost::unsafe;
     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;
    7768                                        }
    7869                                }
     
    8374                        cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
    8475                        if ( Cost::unsafe < cost ) {
    85                                 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    86                                         cost = Cost::unsafe;
     76                                if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
     77                                        if (enumInst->base->isTyped) cost = Cost::unsafe;
    8778                                }
    8879                        }
     
    9283                        cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
    9384                        if ( Cost::unsafe < cost ) {
    94                                 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    95                                         cost = Cost::unsafe;
     85                                if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
     86                                        if (enumInst->base->isTyped) cost = Cost::unsafe;
    9687                                }
    9788                        }
  • src/ResolvExpr/CommonType.cpp

    r4117761 r3c55fcd  
    386386                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    387387                        const ast::EnumDecl* enumDecl = enumInst->base;
    388                         if ( !enumDecl->isCfa ) {
     388                        if ( !enumDecl->base ) {
    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->isCfa ) {
     644                } else if ( param->base && !param->base->isTyped ) {
    645645                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
    646646                        result = commonType( basicType, type2, tenv, need, have, open, widen);
  • src/ResolvExpr/ConversionCost.cpp

    r4117761 r3c55fcd  
    162162Cost conversionCost(
    163163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     164        const 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                 }
    243237        } else {
    244238                assert( -1 == diff );
    245239                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    246240                assert( dstAsRef );
    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 ) ) {
     241                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
    253242                        if ( srcIsLvalue ) {
    254243                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
     
    295284        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    296285                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    297         } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    298                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    299                         cost = Cost::safe;
     286        }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     287                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     288                        cost = Cost::unsafe;
    300289                }
    301290        }
     
    377366        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    378367                cost = enumCastCost(inst, dstInst, symtab, env);
    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();
     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();
    384379}
    385380
     
    459454                // assuming 0p is supposed to be used for pointers?
    460455        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    461                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    462                         cost = Cost::safe;
     456                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     457                        cost = Cost::unsafe;
    463458                }
    464459        }
     
    480475                }
    481476        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    482                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    483                         cost = Cost::safe;
     477                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     478                        cost = Cost::unsafe;
    484479                }
    485480        }
  • src/ResolvExpr/Unify.cpp

    r4117761 r3c55fcd  
    276276        void postvisit( const ast::VoidType * ) {
    277277                result = dynamic_cast< const ast::VoidType * >( type2 );
     278                        // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
     279                ;
    278280        }
    279281
     
    282284                        result = basic->kind == basic2->kind;
    283285                }
     286                // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    284287        }
    285288
     
    290293                                noWiden());
    291294                }
     295                // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    292296        }
    293297
     
    308312                result = unifyExact(
    309313                        array->base, array2->base, tenv, need, have, open, noWiden());
     314                        // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    310315        }
    311316
     
    602607
    603608                result = unifyList( types, types2, tenv, need, have, open );
     609                        // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    604610        }
    605611
    606612        void postvisit( const ast::VarArgsType * ) {
    607613                result = dynamic_cast< const ast::VarArgsType * >( type2 );
     614                        // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    608615        }
    609616
    610617        void postvisit( const ast::ZeroType * ) {
    611618                result = dynamic_cast< const ast::ZeroType * >( type2 );
     619                        // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    612620        }
    613621
    614622        void postvisit( const ast::OneType * ) {
    615623                result = dynamic_cast< const ast::OneType * >( type2 );
     624                        // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    616625        }
    617626};
  • src/Validate/ImplementEnumFunc.cpp

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