Changeset 0522ebe for src/ResolvExpr


Ignore:
Timestamp:
Feb 26, 2024, 3:49:23 AM (4 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
a4da45e
Parents:
c17dc80
Message:

Add EnumPosType? to type system

Location:
src/ResolvExpr
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    rc17dc80 r0522ebe  
    893893                }
    894894                else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    895                         // The Attribute Arrays are not yet generated, need to proxy them
    896                         // as attribute function call
    897                         const CodeLocation & location = cand->expr->location;
    898                         if ( enumInst->base && enumInst->base->base ) {
    899                                 auto valueName = new ast::NameExpr(location, "valueE");
    900                                 auto untypedValueCall = new ast::UntypedExpr(
    901                                         location, valueName, { aggrExpr } );
    902                                 auto result = ResolvExpr::findVoidExpression( untypedValueCall, context );
    903                                 assert( result.get() );
    904                                 CandidateRef newCand = std::make_shared<Candidate>(
    905                                         *cand, result, Cost::safe );
    906                                 candidates.emplace_back( std::move( newCand ) );
    907                         }
     895                        if (enumInst->base && enumInst->base->base) {
     896            const CodeLocation &location = cand->expr->location;
     897
     898            CandidateFinder funcFinder(context, tenv);
     899            auto nameExpr = new ast::NameExpr(location, "valueE");
     900            ResolveMode mode = {true, false, selfFinder.candidates.empty()};
     901            funcFinder.find( nameExpr, mode );
     902
     903            // make variableExpr itself the candidate for the value Call
     904            ExplodedArgs argExpansions;
     905            argExpansions.emplace_back();
     906            auto &argE = argExpansions.back();
     907
     908            argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value
     909
     910            CandidateList found;
     911            SemanticErrorException errors;
     912
     913            for (CandidateRef &func : funcFinder) {
     914                try {
     915                    const ast::Type *funcResult =
     916                        func->expr->result->stripReferences();
     917                    if (auto pointer = dynamic_cast<const ast::PointerType *>(
     918                            funcResult)) {
     919                        if (auto function =
     920                                pointer->base.as<ast::FunctionType>()) {
     921                            CandidateRef newFunc{new Candidate{*func}};
     922                            newFunc->expr = referenceToRvalueConversion(
     923                                newFunc->expr, newFunc->cost);
     924                            makeFunctionCandidates( location,
     925                                                   newFunc, function,
     926                                                   argExpansions, found );
     927                        }
     928                    }
     929                } catch (SemanticErrorException &e) {
     930                    std::cerr
     931                        << "Resolving value function should cause an error"
     932                        << std::endl;
     933                    errors.append(e);
     934                }
     935            }
     936
     937            if (found.empty()) {
     938                std::cerr << "Resolve value function should always success"
     939                          << std::endl;
     940            }
     941
     942            for (CandidateRef &withFunc : found) {
     943                withFunc->cost.incSafe();
     944                Cost cvtCost =
     945                    computeApplicationConversionCost(withFunc, symtab);
     946                assert(cvtCost != Cost::infinity);
     947
     948                candidates.emplace_back(std::move(withFunc));
     949            }
     950        }
    908951                }
    909952        }
     
    14011444        }
    14021445
    1403         void Finder::postvisit( const ast::VariableExpr * variableExpr ) {
    1404                 // not sufficient to just pass `variableExpr` here, type might have changed since
    1405                 addCandidate( variableExpr, tenv );             
    1406         }
     1446    void Finder::postvisit(const ast::VariableExpr *variableExpr) {
     1447        // not sufficient to just pass `variableExpr` here, type might have changed
     1448
     1449        auto cand = new Candidate(variableExpr, tenv);
     1450        candidates.emplace_back(cand);
     1451
     1452        if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(
     1453                variableExpr->var->get_type())) {
     1454            if (enumInst->base && enumInst->base->base) {
     1455                const CodeLocation &location = cand->expr->location;
     1456
     1457                CandidateFinder funcFinder(context, tenv);
     1458                auto nameExpr = new ast::NameExpr(location, "valueE");
     1459                ResolveMode mode = {true, false, selfFinder.candidates.empty()};
     1460                funcFinder.find( nameExpr, mode );
     1461
     1462                // make variableExpr itself the candidate for the value Call
     1463                ExplodedArgs argExpansions;
     1464                argExpansions.emplace_back();
     1465                auto &argE = argExpansions.back();
     1466
     1467                argE.emplace_back(*cand, symtab);
     1468
     1469                CandidateList found;
     1470                SemanticErrorException errors;
     1471
     1472                for (CandidateRef &func : funcFinder) {
     1473                    try {
     1474                    const ast::Type *funcResult =
     1475                        func->expr->result->stripReferences();
     1476                    if (auto pointer = dynamic_cast<const ast::PointerType *>(
     1477                            funcResult)) {
     1478                        if (auto function =
     1479                                pointer->base.as<ast::FunctionType>()) {
     1480                            CandidateRef newFunc{new Candidate{*func}};
     1481                            newFunc->expr = referenceToRvalueConversion(
     1482                                newFunc->expr, newFunc->cost);
     1483                            makeFunctionCandidates(variableExpr->location,
     1484                                                   newFunc, function,
     1485                                                   argExpansions, found);
     1486                        }
     1487                    }
     1488                    } catch (SemanticErrorException &e) {
     1489                        std::cerr
     1490                            << "Resolving value function should cause an error"
     1491                            << std::endl;
     1492                        errors.append(e);
     1493                    }
     1494                }
     1495
     1496                if (found.empty()) {
     1497                    std::cerr << "Resolve value function should always success"
     1498                            << std::endl;
     1499                }
     1500
     1501                for (CandidateRef &withFunc : found) {
     1502                    withFunc->cost.incSafe();
     1503                    Cost cvtCost =
     1504                        computeApplicationConversionCost(withFunc, symtab);
     1505                    assert(cvtCost != Cost::infinity);
     1506
     1507                    candidates.emplace_back(std::move(withFunc));
     1508                }
     1509            }
     1510        }
     1511    }
    14071512
    14081513        void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
  • src/ResolvExpr/CommonType.cc

    rc17dc80 r0522ebe  
    397397                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    398398                                }
     399                        }
     400                } else if ( const ast::EnumPosType * pos = 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 };
    399409                        }
    400410                }
  • src/ResolvExpr/ConversionCost.cc

    rc17dc80 r0522ebe  
    278278        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    279279                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    280         } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     280        }
     281        else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    281282                auto enumDecl = enumInst->base;
    282                 if ( auto baseType = enumDecl->base.get() ) {
    283                         cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
    284                         cost.incUnsafe();
     283                if ( enumDecl->base.get() ) {
     284                        // cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
     285                        // cost.incUnsafe();
     286                        cost = Cost::infinity;
    285287                } else {
    286288            cost = Cost::unsafe;
     
    365367        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    366368        // }
     369        if ( cost < Cost::unsafe ) {
     370                cost.incSafe();
     371        }
     372}
     373
     374void ConversionCost::postvisit( const ast::EnumPosType * ) {
     375        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
     376        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    367377        if ( cost < Cost::unsafe ) {
    368378                cost.incSafe();
  • src/ResolvExpr/ConversionCost.h

    rc17dc80 r0522ebe  
    7272        void postvisit( const ast::ZeroType * zeroType );
    7373        void postvisit( const ast::OneType * oneType );
     74        void postvisit( const ast::EnumPosType * posType );
    7475private:
    7576        // refactor for code resue
  • src/ResolvExpr/Unify.cc

    rc17dc80 r0522ebe  
    517517                }
    518518
     519                void postvisit( const ast::EnumPosType * posType ) {
     520                        // Does nothing for now. Handled in ReplacePseudoFunc
     521                        // Might move here in the future
     522                }
     523
    519524                void postvisit( const ast::TraitInstType * aggrType ) {
    520525                        handleRefType( aggrType, type2 );
Note: See TracChangeset for help on using the changeset viewer.