Changeset 4e08a54 for src/ResolvExpr


Ignore:
Timestamp:
Apr 19, 2024, 12:01:34 PM (23 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master, stuck-waitfor-destruct
Children:
b9b6efb
Parents:
da87eaf (diff), 02c80cdc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    rda87eaf r4e08a54  
    284284                const CodeLocation & location,
    285285                const ast::Type * paramType, const ast::Init * init, const ExplodedArgs & args,
    286                 std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab,
     286                std::vector< ArgPack > & results, std::size_t & genStart, const ResolveContext & context,
    287287                unsigned nTuples = 0
    288288        ) {
     
    294294                                // ^^^ need to handle the case where a tuple has a default argument
    295295                                if ( ! instantiateArgument( location,
    296                                         type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;
     296                                        type, nullptr, args, results, genStart, context, nTuples ) ) return false;
    297297                                nTuples = 0;
    298298                        }
     
    509509
    510510                                // attempt to unify types
    511                                 if ( unify( paramType, argType, env, need, have, open ) ) {
     511                                ast::ptr<ast::Type> common;
     512                                if ( unify( paramType, argType, env, need, have, open, common ) ) {
    512513                                        // add new result
    513                                         results.emplace_back(
    514                                                 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ),
    515                                                 nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     514                                        assert( common );
     515                                                results.emplace_back(
     516                                                        i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ),
     517                                                        nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     518                                        //}
    516519                                }
    517520                        }
     
    785788                                        auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
    786789                                        if ( !instantiateArgument( location,
    787                                                 funcType->params[i], obj->init, args, results, genStart, symtab)) return;
     790                                                funcType->params[i], obj->init, args, results, genStart, context)) return;
    788791                                }
    789792                                goto endMatch;
     
    795798                        // no default args for indirect calls
    796799                        if ( !instantiateArgument( location,
    797                                 param, nullptr, args, results, genStart, symtab ) ) return;
     800                                param, nullptr, args, results, genStart, context ) ) return;
    798801                }
    799802
     
    890893                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    891894                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    892                 }
    893                 else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    894                         if (enumInst->base && enumInst->base->base) {
    895             const CodeLocation &location = cand->expr->location;
    896 
    897             CandidateFinder funcFinder(context, tenv);
    898             auto nameExpr = new ast::NameExpr(location, "valueE");
    899             ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    900             funcFinder.find( nameExpr, mode );
    901 
    902             // make variableExpr itself the candidate for the value Call
    903             ExplodedArgs argExpansions;
    904             argExpansions.emplace_back();
    905             auto &argE = argExpansions.back();
    906 
    907             argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value
    908 
    909             CandidateList found;
    910             SemanticErrorException errors;
    911 
    912             for (CandidateRef &func : funcFinder) {
    913                 try {
    914                     const ast::Type *funcResult =
    915                         func->expr->result->stripReferences();
    916                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    917                             funcResult)) {
    918                         if (auto function =
    919                                 pointer->base.as<ast::FunctionType>()) {
    920                             CandidateRef newFunc{new Candidate{*func}};
    921                             newFunc->expr = referenceToRvalueConversion(
    922                                 newFunc->expr, newFunc->cost);
    923                             makeFunctionCandidates( location,
    924                                                    newFunc, function,
    925                                                    argExpansions, found );
    926                         }
    927                     }
    928                 } catch (SemanticErrorException &e) {
    929                     std::cerr
    930                         << "Resolving value function should cause an error"
    931                         << std::endl;
    932                     errors.append(e);
    933                 }
    934             }
    935 
    936             if (found.empty()) {
    937                 std::cerr << "Resolve value function should always success"
    938                           << std::endl;
    939             }
    940 
    941             for (CandidateRef &withFunc : found) {
    942                 withFunc->cost.incSafe();
    943                 Cost cvtCost =
    944                     computeApplicationConversionCost(withFunc, symtab);
    945                 assert(cvtCost != Cost::infinity);
    946 
    947                 candidates.emplace_back(std::move(withFunc));
    948             }
    949         }
     895                } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
     896                        if ( enumInst->base->base ) {
     897                                CandidateFinder finder( context, tenv );
     898                                auto location = aggrExpr->location;
     899                                auto callExpr = new ast::UntypedExpr(
     900                                        location, new ast::NameExpr( location, "valueE" ), {aggrExpr}
     901                                );
     902                                finder.find( callExpr );
     903                                CandidateList winners = findMinCost( finder.candidates );
     904                                if (winners.size() != 1) {
     905                                        SemanticError( callExpr, "Ambiguous expression in valueE..." );
     906                                }
     907                                CandidateRef & choice = winners.front();
     908                                choice->cost.incVar();
     909                                candidates.emplace_back( std::move(choice) );
     910                        }
     911
    950912                }
    951913        }
     
    14141376                        ast::Expr * newExpr = data.combine( nameExpr->location, cost );
    14151377
     1378                        bool bentConversion = false;
     1379                        if ( auto inst = newExpr->result.as<ast::EnumInstType>() ) {
     1380                                if ( inst->base && inst->base->base ) {
     1381                                        bentConversion = true;
     1382                                }
     1383                        }
     1384
    14161385                        CandidateRef newCand = std::make_shared<Candidate>(
    1417                                 newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
     1386                                newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero,
    14181387                                cost );
    14191388
     
    14481417        auto cand = new Candidate(variableExpr, tenv);
    14491418        candidates.emplace_back(cand);
    1450 
    1451         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(
    1452                 variableExpr->var->get_type())) {
    1453             if (enumInst->base && enumInst->base->base) {
    1454                 const CodeLocation &location = cand->expr->location;
    1455 
    1456                 CandidateFinder funcFinder(context, tenv);
    1457                 auto nameExpr = new ast::NameExpr(location, "valueE");
    1458                 ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    1459                 funcFinder.find( nameExpr, mode );
    1460 
    1461                 // make variableExpr itself the candidate for the value Call
    1462                 ExplodedArgs argExpansions;
    1463                 argExpansions.emplace_back();
    1464                 auto &argE = argExpansions.back();
    1465 
    1466                 argE.emplace_back(*cand, symtab);
    1467 
    1468                 CandidateList found;
    1469                 SemanticErrorException errors;
    1470 
    1471                 for (CandidateRef &func : funcFinder) {
    1472                     try {
    1473                     const ast::Type *funcResult =
    1474                         func->expr->result->stripReferences();
    1475                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    1476                             funcResult)) {
    1477                         if (auto function =
    1478                                 pointer->base.as<ast::FunctionType>()) {
    1479                             CandidateRef newFunc{new Candidate{*func}};
    1480                             newFunc->expr = referenceToRvalueConversion(
    1481                                 newFunc->expr, newFunc->cost);
    1482                             makeFunctionCandidates(variableExpr->location,
    1483                                                    newFunc, function,
    1484                                                    argExpansions, found);
    1485                         }
    1486                     }
    1487                     } catch (SemanticErrorException &e) {
    1488                         std::cerr
    1489                             << "Resolving value function should cause an error"
    1490                             << std::endl;
    1491                         errors.append(e);
    1492                     }
    1493                 }
    1494 
    1495                 if (found.empty()) {
    1496                     std::cerr << "Resolve value function should always success"
    1497                             << std::endl;
    1498                 }
    1499 
    1500                 for (CandidateRef &withFunc : found) {
    1501                     withFunc->cost.incSafe();
    1502                     Cost cvtCost =
    1503                         computeApplicationConversionCost(withFunc, symtab);
    1504                     assert(cvtCost != Cost::infinity);
    1505 
    1506                     candidates.emplace_back(std::move(withFunc));
    1507                 }
    1508             }
    1509         }
    15101419    }
    15111420
     
    18391748
    18401749                                // unification run for side-effects
    1841                                 bool canUnify = unify( toType, cand->expr->result, env, need, have, open );
     1750                                ast::ptr<ast::Type> common;
     1751                                bool canUnify = unify( toType, cand->expr->result, env, need, have, open, common );
    18421752                                (void) canUnify;
    18431753                                Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
     
    18641774                                        // ambiguous case, still output candidates to print in error message
    18651775                                        if ( cand->cost == minExprCost && thisCost == minCastCost ) {
    1866                                                 CandidateRef newCand = std::make_shared<Candidate>(
    1867                                                         new ast::InitExpr{
    1868                                                                 initExpr->location,
    1869                                                                 restructureCast( cand->expr, toType ),
    1870                                                                 initAlt.designation },
    1871                                                         std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
    1872                                                 // currently assertions are always resolved immediately so this should have no effect.
    1873                                                 // if this somehow changes in the future (e.g. delayed by indeterminate return type)
    1874                                                 // we may need to revisit the logic.
    1875                                                 inferParameters( newCand, matches );
     1776                                                auto commonAsEnumAttr = common.as<ast::EnumAttrType>();
     1777                                                if ( commonAsEnumAttr && commonAsEnumAttr->attr == ast::EnumAttribute::Value ) {
     1778                                                        auto callExpr = new ast::UntypedExpr(
     1779                                                                cand->expr->location, new ast::NameExpr( cand->expr->location, "valueE"), {cand->expr} );
     1780                                                        CandidateFinder finder( context, env );
     1781                                                        finder.find( callExpr );
     1782                                                        CandidateList winners = findMinCost( finder.candidates );
     1783                                                        if (winners.size() != 1) {
     1784                                                                SemanticError( callExpr, "Ambiguous expression in valueE..." );
     1785                                                        }
     1786                                                        CandidateRef & choice = winners.front();
     1787                                                        // assert( valueCall->result );
     1788                                                        CandidateRef newCand = std::make_shared<Candidate>(
     1789                                                                new ast::InitExpr{
     1790                                                                        initExpr->location,
     1791                                                                        // restructureCast( cand->expr, toType ),
     1792                                                                        choice->expr,
     1793                                                                        initAlt.designation },
     1794                                                                std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
     1795                                                                inferParameters( newCand, matches );
     1796                                                } else {
     1797                                                        CandidateRef newCand = std::make_shared<Candidate>(
     1798                                                                new ast::InitExpr{
     1799                                                                        initExpr->location,
     1800                                                                        restructureCast( cand->expr, toType ),
     1801                                                                        initAlt.designation },
     1802                                                                std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
     1803                                                        // currently assertions are always resolved immediately so this should have no effect.
     1804                                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
     1805                                                        // we may need to revisit the logic.
     1806                                                        inferParameters( newCand, matches );
     1807                                                }
    18761808                                        }
    18771809                                }
     
    19001832                                                std::make_shared<Candidate>(
    19011833                                                        newExpr, copy( tenv ), ast::OpenVarSet{},
    1902                                                         ast::AssertionSet{}, Cost::zero, cost
     1834                                                        ast::AssertionSet{}, Cost::safe, cost
    19031835                                                );
    19041836
     
    22002132}
    22012133
     2134// get the valueE(...) ApplicationExpr that returns the enum value
     2135const ast::Expr * getValueEnumCall(
     2136        const ast::Expr * expr,
     2137        const ResolvExpr::ResolveContext & context, const ast::TypeEnvironment & env ) {
     2138                auto callExpr = new ast::UntypedExpr(
     2139                        expr->location, new ast::NameExpr( expr->location, "valueE"), {expr} );
     2140                CandidateFinder finder( context, env );
     2141                finder.find( callExpr );
     2142                CandidateList winners = findMinCost( finder.candidates );
     2143                if (winners.size() != 1) {
     2144                        SemanticError( callExpr, "Ambiguous expression in valueE..." );
     2145                }
     2146                CandidateRef & choice = winners.front();
     2147                return choice->expr;
     2148}
     2149
    22022150const ast::Expr * createCondExpr( const ast::Expr * expr ) {
    22032151        assert( expr );
     
    22122160                        }
    22132161                ),
    2214                 new ast::BasicType( ast::BasicType::SignedInt )
     2162                new ast::BasicType( ast::BasicKind::SignedInt )
    22152163        );
    22162164}
  • src/ResolvExpr/CandidateFinder.hpp

    rda87eaf r4e08a54  
    3030struct CandidateFinder {
    3131        CandidateList candidates;          ///< List of candidate resolutions
    32         const ResolveContext & context;  ///< Information about where the canditates are being found.
     32        const ResolveContext & context;    ///< Information about where the canditates are being found.
    3333        const ast::TypeEnvironment & env;  ///< Substitutions performed in this resolution
    3434        ast::ptr< ast::Type > targetType;  ///< Target type for resolution
    3535        bool strictMode = false;           ///< If set to true, requires targetType to be exact match (inside return cast)
    3636        bool allowVoid = false;            ///< If set to true, allow void-returning function calls (only top level, cast to void and first in comma)
    37         std::set< std::string > otypeKeys;  /// different type may map to same key
     37        std::set< std::string > otypeKeys; ///< different type may map to same key
    3838
    3939        CandidateFinder(
     
    7070        const ast::Expr * expr, Cost & cost );
    7171
     72/// Get the valueE application that returns the enum's value.
     73const ast::Expr * getValueEnumCall( const ast::Expr * expr,
     74        const ResolveContext & context, const ast::TypeEnvironment & env );
     75
    7276/// Wrap an expression to convert the result to a conditional result.
    7377const ast::Expr * createCondExpr( const ast::Expr * expr );
  • src/ResolvExpr/CommonType.cc

    rda87eaf r4e08a54  
    3838        // GENERATED START, DO NOT EDIT
    3939        // GENERATED BY BasicTypes-gen.cc
    40         #define BT ast::BasicType::
    41         static const BT Kind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
     40        #define BT ast::BasicKind::
     41        static const ast::BasicKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
    4242                /*                                      B                       C                      SC                      UC                      SI                     SUI
    4343                                                        I                      UI                      LI                     LUI                     LLI                    LLUI
     
    339339        // GENERATED END
    340340        static_assert(
    341                 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,
     341                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
    342342                "Each basic type kind should have a corresponding row in the combined type matrix"
    343343        );
     
    366366        void postvisit( const ast::BasicType * basic ) {
    367367                if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
    368                         ast::BasicType::Kind kind;
     368                        ast::BasicKind kind;
    369369                        if (basic->kind != basic2->kind && !widen.first && !widen.second) return;
    370370                        else if (!widen.first) kind = basic->kind; // widen.second
     
    385385                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    386386                        const ast::EnumDecl* enumDecl = enumInst->base;
    387                         if ( enumDecl->base ) {
    388                                 result = enumDecl->base.get();
    389                         } else {
    390                                 ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::SignedInt ];
     387                        if ( !enumDecl->base ) {
     388                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    391389                                if (
    392390                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     
    398396                                }
    399397                        }
    400                 } else if ( dynamic_cast< const ast::EnumPosType * >( type2 ) ) {
    401                         ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::SignedInt ];
    402                         if (
    403                                 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
    404                                         || widen.first )
    405                                 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    406                                         || widen.second )
    407                         ) {
    408                                 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    409                         }
     398                } else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) {
     399            if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) {
     400                            ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
     401                            if (
     402                                    ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     403                                            || widen.first )
     404                                    && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
     405                                            || widen.second )
     406                            ) {
     407                                    result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     408                            }
     409            }
    410410                }
    411411        }
     
    426426                result = voidPtr;
    427427                add_qualifiers( result, oPtr->qualifiers );
    428         }
    429 
    430         // For a typed enum, we want to unify type1 with the base type of the enum
    431         bool tryResolveWithTypedEnum( const ast::Type * type1 ) {
    432                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {
    433                         ast::OpenVarSet newOpen{ open };
    434                         if (enumInst->base->base
    435                                 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen)) {
    436                                         result = type1;
    437                                 return true;
    438                         }
    439                 }
    440                 return false;
    441428        }
    442429
     
    607594                        result = pointer;
    608595                        add_qualifiers( result, type2->qualifiers );
    609                 } else {
    610                         tryResolveWithTypedEnum( pointer );
    611                 }
    612         }
    613 
    614         void postvisit( const ast::ArrayType * arr ) {
    615                 // xxx - does it make sense?
    616                 tryResolveWithTypedEnum( arr );
    617         }
     596                }
     597        }
     598
     599        void postvisit( const ast::ArrayType * ) {}
    618600
    619601        void postvisit( const ast::ReferenceType * ref ) {
     
    659641        }
    660642
    661         void postvisit( const ast::FunctionType * func) {
    662                 tryResolveWithTypedEnum( func );
    663         }
    664 
    665         void postvisit( const ast::StructInstType * inst ) {
    666                 tryResolveWithTypedEnum( inst );
    667         }
    668 
    669         void postvisit( const ast::UnionInstType * inst ) {
    670                 tryResolveWithTypedEnum( inst );
    671         }
     643        void postvisit( const ast::FunctionType * ) {}
     644
     645        void postvisit( const ast::StructInstType * ) {}
     646
     647        void postvisit( const ast::UnionInstType * ) {}
    672648
    673649        void postvisit( const ast::EnumInstType * enumInst ) {
    674                 // if ( dynamic_cast<const ast::EnumPosType *>(enumInst) ) {
    675                 //      result = enumInst;
    676                 // } else
    677                 if (!dynamic_cast<const ast::EnumInstType *>(type2)) {
    678                         result = commonType( type2, enumInst, tenv, need, have, open, widen);
    679                 }
    680         }
    681 
    682         void postvisit( const ast::EnumPosType * enumPos ) {
    683                 if ( auto type2AsPos = dynamic_cast<const ast::EnumPosType *>(type2) ) {
    684                         // result = commonType( type2AsPos->instance, enumPos->instance, tenv, need, have, open, widen );
    685                         // result = enumPos;
    686                         if ( enumPos->instance->base->name == type2AsPos->instance->base->name ) {
    687                                 result = type2;
    688                         }
    689                 } else if ( dynamic_cast<const ast::BasicType *>(type2) ) {
    690                         result = type2;
    691                 }
    692         }
     650                if ( enumInst->base && !enumInst->base->base ) {
     651                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
     652                        result = commonType( basicType, type2, tenv, need, have, open, widen);
     653                }
     654        }
     655
     656        void postvisit( const ast::EnumAttrType * ) {}
    693657
    694658        void postvisit( const ast::TraitInstType * ) {}
     
    696660        void postvisit( const ast::TypeInstType * ) {}
    697661
    698         void postvisit( const ast::TupleType * tuple ) {
    699                 tryResolveWithTypedEnum( tuple );
    700         }
     662        void postvisit( const ast::TupleType * ) {}
    701663
    702664        void postvisit( const ast::VarArgsType * ) {}
     
    712674                } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
    713675                        result = new ast::BasicType{
    714                                 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
     676                                ast::BasicKind::SignedInt, zero->qualifiers | type2->qualifiers };
    715677                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    716678                        const ast::EnumDecl * enumDecl = enumInst->base;
    717                         if ( enumDecl->base ) {
    718                                 if ( tryResolveWithTypedEnum( zero ) )
    719                                         add_qualifiers( result, zero->qualifiers );
    720                         } else {
     679                        if ( !enumDecl->base ) {
    721680                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
    722681                                        result = type2;
     
    736695                } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
    737696                        result = new ast::BasicType{
    738                                 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
     697                                ast::BasicKind::SignedInt, one->qualifiers | type2->qualifiers };
    739698                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    740                         const ast::EnumDecl * enumBase = enumInst->base;
    741                         if ( enumBase->base ) {
    742                                 if ( tryResolveWithTypedEnum( one ))
    743                                         add_qualifiers( result, one->qualifiers );
    744                         } else {
     699                        const ast::EnumDecl * enumDecl = enumInst->base;
     700                        if ( !enumDecl->base ) {
    745701                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
    746702                                        result = type2;
  • src/ResolvExpr/ConversionCost.cc

    rda87eaf r4e08a54  
    5959        // GENERATED START, DO NOT EDIT
    6060        // GENERATED BY BasicTypes-gen.cc
    61         static const int costMatrix[ast::BasicType::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
     61        static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
    6262                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    6363                /*      B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
     
    101101        // GENERATED END
    102102        static_assert(
    103                 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,
     103                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
    104104                "Missing row in the cost matrix"
    105105        );
     
    107107        // GENERATED START, DO NOT EDIT
    108108        // GENERATED BY BasicTypes-gen.cc
    109         static const int signMatrix[ast::BasicType::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
     109        static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
    110110                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    111111                /*      B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     
    148148        // GENERATED END
    149149        static_assert(
    150                 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,
     150                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
    151151                "Missing row in the sign matrix"
    152152        );
     
    278278        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    279279                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    280         }
    281         else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    282                 auto enumDecl = enumInst->base;
    283                 if ( enumDecl->base.get() ) {
    284                         // cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
    285                         // cost.incUnsafe();
    286                         cost = Cost::infinity;
    287                 } else {
    288             cost = Cost::unsafe;
    289                 }
    290         } else if ( dynamic_cast< const ast::EnumPosType *>(dst) ) {
    291                 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
     280        } else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) {
     281                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    292282                cost = costCalc( basicType, integer, srcIsLvalue, symtab, env );
     283        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     284                if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
     285                        cost = Cost::zero;
     286                        cost.incUnsafe();
     287                }
    293288        }
    294289}
     
    366361}
    367362
    368 void ConversionCost::postvisit( const ast::EnumInstType * ) {
    369         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
     363void 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                }
     371                return;
     372        }
     373        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    370374        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    371375        if ( cost < Cost::unsafe ) {
     
    374378}
    375379
    376 void ConversionCost::postvisit( const ast::EnumPosType * src ) {
    377         if ( dynamic_cast<const ast::EnumPosType *>( dst ) ) {
    378                 // cost = costCalc( src->instance, dstBase->instance, srcIsLvalue, symtab, env );
    379                 // if ( cost < Cost::unsafe ) cost.incSafe();
    380                 cost = Cost::zero;
    381         } else if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    382                 cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
    383                 if ( cost < Cost::unsafe ) cost.incSafe();
    384         } else {
    385                 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    386                 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    387                 if ( cost < Cost::unsafe ) {
    388                         cost.incSafe();
    389                 }
    390         }
    391 
     380void 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    }
    392405}
    393406
     
    448461        } else if ( const ast::BasicType * dstAsBasic =
    449462                        dynamic_cast< const ast::BasicType * >( dst ) ) {
    450                 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
     463                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
    451464                if ( -1 == tableResult ) {
    452465                        cost = Cost::unsafe;
     
    454467                        cost = Cost::zero;
    455468                        cost.incSafe( tableResult + 1 );
    456                         cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
     469                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
    457470                }
    458471                // this has the effect of letting any expr such as x+0, x+1 to be typed
     
    466479                cost.incSafe( maxIntCost + 2 );
    467480                // assuming 0p is supposed to be used for pointers?
     481        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     482                if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
     483                        cost = Cost::zero;
     484                        cost.incUnsafe();
     485                }
    468486        }
    469487}
     
    475493        } else if ( const ast::BasicType * dstAsBasic =
    476494                        dynamic_cast< const ast::BasicType * >( dst ) ) {
    477                 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
     495                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
    478496                if ( -1 == tableResult ) {
    479497                        cost = Cost::unsafe;
     
    481499                        cost = Cost::zero;
    482500                        cost.incSafe( tableResult + 1 );
    483                         cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
     501                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
     502                }
     503        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     504                if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
     505                        cost = Cost::zero;
     506                        cost.incUnsafe();
    484507                }
    485508        }
  • src/ResolvExpr/ConversionCost.h

    rda87eaf r4e08a54  
    7272        void postvisit( const ast::ZeroType * zeroType );
    7373        void postvisit( const ast::OneType * oneType );
    74         void postvisit( const ast::EnumPosType * posType );
     74        void postvisit( const ast::EnumAttrType * posType );
    7575private:
    7676        // refactor for code resue
  • src/ResolvExpr/PtrsCastable.cc

    rda87eaf r4e08a54  
    100100                                result = 1;
    101101                        } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
    102                                 if ( bt->kind == ast::BasicType::SignedInt ) {
     102                                if ( bt->kind == ast::BasicKind::SignedInt ) {
    103103                                        result = 0;
    104104                                } else {
  • src/ResolvExpr/ResolveTypeof.cc

    rda87eaf r4e08a54  
    6363                        if ( newType.as< ast::EnumInstType >() ) {
    6464                                newType = new ast::BasicType(
    65                                         ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) );
     65                                        ast::BasicKind::SignedInt, newType->qualifiers, copy(newType->attributes) );
    6666                        }
    6767                        reset_qualifiers(
     
    9191                auto mutType = mutate(arrayType);
    9292                auto globalSizeType = context.global.sizeType;
    93                 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
     93                ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType( ast::BasicKind::LongUnsignedInt );
    9494                mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
    9595
  • src/ResolvExpr/Resolver.cc

    rda87eaf r4e08a54  
    351351        bool isCharType( const ast::Type * t ) {
    352352                if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
    353                         return bt->kind == ast::BasicType::Char
    354                                 || bt->kind == ast::BasicType::SignedChar
    355                                 || bt->kind == ast::BasicType::UnsignedChar;
     353                        return bt->kind == ast::BasicKind::Char
     354                                || bt->kind == ast::BasicKind::SignedChar
     355                                || bt->kind == ast::BasicKind::UnsignedChar;
    356356                }
    357357                return false;
     
    458458                        if (attr->params.size() == 1) {
    459459                                auto arg = attr->params.front();
    460                                 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), context );
     460                                auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicKind::LongLongSignedInt ), context );
    461461                                auto result = eval(arg);
    462462
     
    624624                        objectDecl = fixObjectType( objectDecl, context );
    625625                        currentObject = ast::CurrentObject{
    626                                 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
     626                                objectDecl->location, new ast::BasicType{ ast::BasicKind::SignedInt } };
    627627                }
    628628        } else {
     
    10951095                // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally
    10961096                ast::ptr< ast::Type > target =
    1097                         new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
     1097                        new ast::BasicType{ ast::BasicKind::LongLongUnsignedInt };
    10981098                auto timeout_time = findSingleExpression( stmt->timeout_time, target, context );
    10991099                auto timeout_cond = findCondExpression( stmt->timeout_cond, context );
  • src/ResolvExpr/Unify.cc

    rda87eaf r4e08a54  
    274274                void previsit( const ast::Node * ) { visit_children = false; }
    275275
    276                 void postvisit( const ast::VoidType * ) {
    277                         result = dynamic_cast< const ast::VoidType * >( type2 );
     276                void postvisit( const ast::VoidType * vt) {
     277                        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
     
    307311
    308312                        result = unifyExact(
    309                                 array->base, array2->base, tenv, need, have, open, noWiden());
     313                                array->base, array2->base, tenv, need, have, open, noWiden())
     314                                || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    310315                }
    311316
     
    399404                }
    400405
     406                bool tryToUnifyWithEnumValue( const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     407                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     408                        WidenMode widen) {
     409                        if ( auto attrType2 = dynamic_cast<const ast::EnumAttrType *>(type2)) {
     410                                if (attrType2->attr == ast::EnumAttribute::Value) {
     411                                        return unifyExact( type1, attrType2->instance->base->base, env, need, have, open,
     412                                                widen);
     413                                } else if (attrType2->attr == ast::EnumAttribute::Posn) {
     414                                        return unifyExact( type1, attrType2->instance, env, need, have, open, widen );
     415                                }
     416                        }
     417                        return false;
     418                }
     419
    401420        public:
    402421                void postvisit( const ast::FunctionType * func ) {
     
    507526                void postvisit( const ast::StructInstType * aggrType ) {
    508527                        handleGenericRefType( aggrType, type2 );
     528                        result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    509529                }
    510530
    511531                void postvisit( const ast::UnionInstType * aggrType ) {
    512532                        handleGenericRefType( aggrType, type2 );
     533                        result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    513534                }
    514535
    515536                void postvisit( const ast::EnumInstType * aggrType ) {
    516537                        handleRefType( aggrType, type2 );
    517                 }
    518 
    519                 void postvisit( const ast::EnumPosType * posType ) {
     538                        result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
     539                }
     540
     541                void postvisit( const ast::EnumAttrType * enumAttr ) {
    520542                        // Lazy approach for now
    521                         auto otherPos = dynamic_cast< const ast::EnumPosType *>(type2);
    522                         if ( otherPos ) {
    523                                 if ( otherPos->instance->base->name == posType->instance->base->name )
    524                                         result = otherPos;
    525                         }
     543                        if ( auto otherPos = dynamic_cast< const ast::EnumAttrType *>(type2) ) {
     544                            if ( enumAttr->match(otherPos) ) {
     545                                    result = otherPos;
     546                            }
     547            } 
    526548                }
    527549
    528550                void postvisit( const ast::TraitInstType * aggrType ) {
    529551                        handleRefType( aggrType, type2 );
     552                        result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    530553                }
    531554
     
    536559                                this->result = otherInst;
    537560                        }
     561                        result = result || tryToUnifyWithEnumValue(typeInst, type2, tenv, need, have, open, noWiden());
    538562                }
    539563
     
    610634                        auto types2 = flatten( flat2 );
    611635
    612                         result = unifyList( types, types2, tenv, need, have, open );
    613                 }
    614 
    615                 void postvisit( const ast::VarArgsType * ) {
    616                         result = dynamic_cast< const ast::VarArgsType * >( type2 );
    617                 }
    618 
    619                 void postvisit( const ast::ZeroType * ) {
    620                         result = dynamic_cast< const ast::ZeroType * >( type2 );
    621                 }
    622 
    623                 void postvisit( const ast::OneType * ) {
    624                         result = dynamic_cast< const ast::OneType * >( type2 );
     636                        result = unifyList( types, types2, tenv, need, have, open )
     637                                || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
     638                }
     639
     640                void postvisit( const ast::VarArgsType * vat) {
     641                        result = dynamic_cast< const ast::VarArgsType * >( type2 )
     642                                || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
     643                }
     644
     645                void postvisit( const ast::ZeroType * zt) {
     646                        result = dynamic_cast< const ast::ZeroType * >( type2 )
     647                                || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
     648                }
     649
     650                void postvisit( const ast::OneType * ot) {
     651                        result = dynamic_cast< const ast::OneType * >( type2 )
     652                                || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    625653                }
    626654        };
Note: See TracChangeset for help on using the changeset viewer.