Changeset 5ccc733


Ignore:
Timestamp:
Jun 29, 2024, 5:02:06 AM (3 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
4117761
Parents:
7552fde
Message:

Fix the bug that C style enum cannot to use as an lvalue

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

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

    r7552fde r5ccc733  
    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/ControlStruct/TranslateEnumRange.cpp

    r7552fde r5ccc733  
    9191    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
    9292        "?<=?",
    93         {
    94             ast::UntypedExpr::createCall(location, "posn", { new ast::NameExpr( location, indexName ) } ),
    95             ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 )
    96         });
     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 ) });
     98
    9799    auto increment = ast::UntypedExpr::createCall( location,
    98         stmt->is_inc? "succ": "pred",
     100        stmt->is_inc? "?++": "?--",
    99101        { new ast::NameExpr( location, indexName ) });
     102   
    100103    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    101104    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • src/Parser/TypeData.cpp

    r7552fde r5ccc733  
    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/ResolvExpr/CastCost.cpp

    r7552fde r5ccc733  
    5454                        cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
    5555
    56                         if (Cost::unsafe < cost) {
     56                        if ( !enumInst->base->isCfa ) {
    5757                                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    5858                                Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    5959                                cost = intCost < cost? intCost: cost;
    60                         }
    61                         if ( enumInst->base->isTyped && enumInst->base->base ) {
     60                        } else if ( enumInst->base->isTyped() ) {
    6261                                auto baseConversionCost =
    6362                                        castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
     
    7473                                cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
    7574                                if ( Cost::unsafe < cost ) {
    76                                         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    77                                                 // Always explict cast only for typed enum
    78                                                 if (enumInst->base->isTyped) cost = Cost::unsafe;
     75                                        if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     76                                                cost = Cost::unsafe;
    7977                                        }
    8078                                }
     
    8583                        cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
    8684                        if ( Cost::unsafe < cost ) {
    87                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    88                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     85                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     86                                        cost = Cost::unsafe;
    8987                                }
    9088                        }
     
    9492                        cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
    9593                        if ( Cost::unsafe < cost ) {
    96                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    97                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     94                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     95                                        cost = Cost::unsafe;
    9896                                }
    9997                        }
  • src/ResolvExpr/CommonType.cpp

    r7552fde r5ccc733  
    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

    r7552fde r5ccc733  
    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 ) {
     
    285296                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    286297        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    287                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    288                         cost = Cost::unsafe;
     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 
    371         if ( !inst->base->isTyped ) {
     379        } else if ( !inst->base->isCfa ) {
    372380                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    373381                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    374                 if ( cost < Cost::unsafe ) {
    375                         cost.incSafe();
    376                 }
    377                 return;
    378382        }
    379383        // cost.incUnsafe();
     
    455459                // assuming 0p is supposed to be used for pointers?
    456460        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    457                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    458                         cost = Cost::unsafe;
     461                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     462                        cost = Cost::safe;
    459463                }
    460464        }
     
    476480                }
    477481        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    478                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    479                         cost = Cost::unsafe;
     482                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     483                        cost = Cost::safe;
    480484                }
    481485        }
  • src/Validate/ImplementEnumFunc.cpp

    r7552fde r5ccc733  
    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.