Ignore:
Timestamp:
Feb 26, 2024, 8:17:20 AM (8 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
f1149ac
Parents:
1bb76ad (diff), a4da45e (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r1bb76ad r3f9a8d0  
    891891                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    892892                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    893                 } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    894                         // The Attribute Arrays are not yet generated, need to proxy them
    895                         // as attribute function call
    896                         const CodeLocation & location = cand->expr->location;
    897                         if ( enumInst->base && enumInst->base->base ) {
    898                                 auto valueName = new ast::NameExpr(location, "valueE");
    899                                 auto untypedValueCall = new ast::UntypedExpr(
    900                                         location, valueName, { aggrExpr } );
    901                                 auto result = ResolvExpr::findVoidExpression( untypedValueCall, context );
    902                                 assert( result.get() );
    903                                 CandidateRef newCand = std::make_shared<Candidate>(
    904                                         *cand, result, Cost::safe );
    905                                 candidates.emplace_back( std::move( newCand ) );
    906                         }
     893                }
     894                else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
     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        }
    907951                }
    908952        }
     
    14001444        }
    14011445
    1402         void Finder::postvisit( const ast::VariableExpr * variableExpr ) {
    1403                 // not sufficient to just pass `variableExpr` here, type might have changed since
    1404                 addCandidate( variableExpr, tenv );
    1405         }
     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    }
    14061512
    14071513        void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
Note: See TracChangeset for help on using the changeset viewer.