Ignore:
Timestamp:
Nov 25, 2020, 12:25:06 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6f1e695
Parents:
04994aa (diff), 5e82d56 (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

    r04994aa rb3ed43a3  
    4343#include "SymTab/Validate.h"      // for validateType
    4444#include "Tuples/Tuples.h"        // for handleTupleAssignment
     45#include "InitTweak/InitTweak.h"  // for getPointerBase
     46
     47#include "Common/Stats/Counter.h"
    4548
    4649#define PRINT( text ) if ( resolvep ) { text }
     
    864867
    865868                void postvisit( const ast::UntypedExpr * untypedExpr ) {
    866                         CandidateFinder funcFinder{ symtab, tenv };
    867                         funcFinder.find( untypedExpr->func, ResolvMode::withAdjustment() );
    868                         // short-circuit if no candidates
    869                         if ( funcFinder.candidates.empty() ) return;
    870 
    871                         reason.code = NoMatch;
    872 
    873869                        std::vector< CandidateFinder > argCandidates =
    874870                                selfFinder.findSubExprs( untypedExpr->args );
     
    877873                        // if not tuple assignment, handled as normal function call
    878874                        Tuples::handleTupleAssignment( selfFinder, untypedExpr, argCandidates );
     875
     876                        CandidateFinder funcFinder{ symtab, tenv };
     877                        if (auto nameExpr = untypedExpr->func.as<ast::NameExpr>()) {
     878                                auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
     879                                if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
     880                                        assertf(!argCandidates.empty(), "special function call without argument");
     881                                        for (auto & firstArgCand: argCandidates[0]) {
     882                                                ast::ptr<ast::Type> argType = firstArgCand->expr->result;
     883                                                firstArgCand->env.apply(argType);
     884                                                // strip references
     885                                                // xxx - is this correct?
     886                                                while (argType.as<ast::ReferenceType>()) argType = argType.as<ast::ReferenceType>()->base;
     887
     888                                                // convert 1-tuple to plain type
     889                                                if (auto tuple = argType.as<ast::TupleType>()) {
     890                                                        if (tuple->size() == 1) {
     891                                                                argType = tuple->types[0];
     892                                                        }
     893                                                }
     894                                               
     895                                                // if argType is an unbound type parameter, all special functions need to be searched.
     896                                                if (isUnboundType(argType)) {
     897                                                        funcFinder.otypeKeys.clear();
     898                                                        break;
     899                                                }
     900
     901                                                if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);
     902                                                else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type));
     903                                        }
     904                                }
     905                        }
     906                        // if candidates are already produced, do not fail
     907                        // xxx - is it possible that handleTupleAssignment and main finder both produce candidates?
     908                        // this means there exists ctor/assign functions with a tuple as first parameter.
     909                        funcFinder.find( untypedExpr->func, selfFinder.candidates.empty() ? ResolvMode::withAdjustment() : ResolvMode::withoutFailFast() );
     910                        // short-circuit if no candidates
     911                        // if ( funcFinder.candidates.empty() ) return;
     912
     913                        reason.code = NoMatch;
    879914
    880915                        // find function operators
     
    10661101                                // unification run for side-effects
    10671102                                unify( toType, cand->expr->result, cand->env, need, have, open, symtab );
    1068                                 Cost thisCost = castCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    1069                                                 symtab, cand->env );
     1103                                Cost thisCost =
     1104                                        (castExpr->isGenerated == ast::GeneratedFlag::GeneratedCast)
     1105                            ? conversionCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env )
     1106                            : castCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env );
     1107
    10701108                                PRINT(
    10711109                                        std::cerr << "working on cast with result: " << toType << std::endl;
     
    11871225
    11881226                void postvisit( const ast::NameExpr * nameExpr ) {
    1189                         std::vector< ast::SymbolTable::IdData > declList = symtab.lookupId( nameExpr->name );
     1227                        std::vector< ast::SymbolTable::IdData > declList;
     1228                        if (!selfFinder.otypeKeys.empty()) {
     1229                                auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
     1230                                assertf(kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS, "special lookup with non-special target: %s", nameExpr->name.c_str());
     1231
     1232                                for (auto & otypeKey: selfFinder.otypeKeys) {
     1233                                        auto result = symtab.specialLookupId(kind, otypeKey);
     1234                                        declList.insert(declList.end(), std::make_move_iterator(result.begin()), std::make_move_iterator(result.end()));
     1235                                }
     1236                        }
     1237                        else {
     1238                                declList = symtab.lookupId( nameExpr->name );
     1239                        }
    11901240                        PRINT( std::cerr << "nameExpr is " << nameExpr->name << std::endl; )
     1241
    11911242                        if( declList.empty() ) return;
    11921243
     
    15431594
    15441595                                        // unification run for side-effects
    1545                                         unify( toType, cand->expr->result, env, need, have, open, symtab );
     1596                                        bool canUnify = unify( toType, cand->expr->result, env, need, have, open, symtab );
     1597                                        (void) canUnify;
    15461598                                        Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
     1599                                                symtab, env );
     1600                                        PRINT(
     1601                                                Cost legacyCost = castCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    15471602                                                        symtab, env );
    1548 
     1603                                                std::cerr << "Considering initialization:";
     1604                                                std::cerr << std::endl << "  FROM: " << cand->expr->result << std::endl;
     1605                                                std::cerr << std::endl << "  TO: "   << toType             << std::endl;
     1606                                                std::cerr << std::endl << "  Unification " << (canUnify ? "succeeded" : "failed");
     1607                                                std::cerr << std::endl << "  Legacy cost " << legacyCost;
     1608                                                std::cerr << std::endl << "  New cost " << thisCost;
     1609                                                std::cerr << std::endl;
     1610                                        )
    15491611                                        if ( thisCost != Cost::infinity ) {
    15501612                                                // count one safe conversion for each value that is thrown away
     
    15581620                                        }
    15591621                                }
     1622
    15601623                        }
    15611624
Note: See TracChangeset for help on using the changeset viewer.