Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r5ccb10d rddf8a29  
    1414//
    1515
    16 #include <list>
    17 #include <iterator>
    18 #include <algorithm>
    19 #include <functional>
    20 #include <cassert>
    21 #include <unordered_map>
    22 #include <utility>
    23 #include <vector>
    24 
     16#include <algorithm>               // for copy
     17#include <cassert>                 // for safe_dynamic_cast, assert, assertf
     18#include <iostream>                // for operator<<, cerr, ostream, endl
     19#include <iterator>                // for back_insert_iterator, back_inserter
     20#include <list>                    // for _List_iterator, list, _List_const_...
     21#include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
     22#include <memory>                  // for allocator_traits<>::value_type
     23#include <utility>                 // for pair
     24
     25#include "Alternative.h"           // for AltList, Alternative
    2526#include "AlternativeFinder.h"
    26 #include "Alternative.h"
    27 #include "Cost.h"
    28 #include "typeops.h"
    29 #include "Unify.h"
    30 #include "RenameVars.h"
    31 #include "SynTree/Type.h"
    32 #include "SynTree/Declaration.h"
    33 #include "SynTree/Expression.h"
    34 #include "SynTree/Initializer.h"
    35 #include "SynTree/Visitor.h"
    36 #include "SymTab/Indexer.h"
    37 #include "SymTab/Mangler.h"
    38 #include "SynTree/TypeSubstitution.h"
    39 #include "SymTab/Validate.h"
    40 #include "Tuples/Tuples.h"
    41 #include "Tuples/Explode.h"
    42 #include "Common/utility.h"
    43 #include "InitTweak/InitTweak.h"
    44 #include "InitTweak/GenInit.h"
    45 #include "ResolveTypeof.h"
    46 #include "Resolver.h"
     27#include "Common/SemanticError.h"  // for SemanticError
     28#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
     29#include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
     30#include "InitTweak/InitTweak.h"   // for getFunctionName
     31#include "RenameVars.h"            // for RenameVars, global_renamer
     32#include "ResolveTypeof.h"         // for resolveTypeof
     33#include "Resolver.h"              // for resolveStmtExpr
     34#include "SymTab/Indexer.h"        // for Indexer
     35#include "SymTab/Mangler.h"        // for Mangler
     36#include "SymTab/Validate.h"       // for validateType
     37#include "SynTree/Constant.h"      // for Constant
     38#include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
     39#include "SynTree/Expression.h"    // for Expression, CastExpr, NameExpr
     40#include "SynTree/Initializer.h"   // for SingleInit, operator<<, Designation
     41#include "SynTree/SynTree.h"       // for UniqueId
     42#include "SynTree/Type.h"          // for Type, FunctionType, PointerType
     43#include "Tuples/Explode.h"        // for explode
     44#include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
     45#include "Unify.h"                 // for unify
     46#include "typeops.h"               // for adjustExprType, polyCost, castCost
    4747
    4848extern bool resolvep;
     
    286286        }
    287287
    288         Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     288        Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     289                PRINT(
     290                        std::cerr << std::endl << "converting ";
     291                        actualType->print( std::cerr, 8 );
     292                        std::cerr << std::endl << " to ";
     293                        formalType->print( std::cerr, 8 );
     294                        std::cerr << std::endl << "environment is: ";
     295                        env.print( std::cerr, 8 );
     296                        std::cerr << std::endl;
     297                )
     298                Cost convCost = conversionCost( actualType, formalType, indexer, env );
     299                PRINT(
     300                        std::cerr << std::endl << "cost is" << convCost << std::endl;
     301                )
     302                if ( convCost == Cost::infinity ) {
     303                        return convCost;
     304                }
     305                convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
     306                return convCost;
     307        }
     308
     309        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     310                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
     311                // if ( convCost != Cost::zero ) {
     312
     313                // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
     314                // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
     315                // previous line.
     316                Cost tmpCost = convCost;
     317                tmpCost.incPoly( -tmpCost.get_polyCost() );
     318                if ( tmpCost != Cost::zero ) {
     319                        Type *newType = formalType->clone();
     320                        env.apply( newType );
     321                        actualExpr = new CastExpr( actualExpr, newType );
     322                        // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
     323                        // inconsistent, once this is fixed it should be possible to resolve the cast.
     324                        // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
     325
     326                        // AlternativeFinder finder( indexer, env );
     327                        // finder.findWithAdjustment( actualExpr );
     328                        // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
     329                        // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
     330                        // Alternative & alt = finder.get_alternatives().front();
     331                        // delete actualExpr;
     332                        // actualExpr = alt.expr->clone();
     333                }
     334                return convCost;
     335        }
     336
     337        Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    289338                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    290339                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     
    304353                                actualType->print( std::cerr, 8 );
    305354                        )
    306                         Cost actualCost = Cost::zero;
    307355                        if ( formal == formals.end() ) {
    308356                                if ( function->get_isVarArgs() ) {
     
    325373                                std::cerr << std::endl;
    326374                        )
    327                         Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
    328                         PRINT(
    329                                 std::cerr << std::endl << "cost is" << newCost << std::endl;
    330                         )
    331 
    332                         if ( newCost == Cost::infinity ) {
    333                                 return newCost;
    334                         }
    335                         convCost += newCost;
    336                         actualCost += newCost;
    337                         if ( actualCost != Cost::zero ) {
    338                                 Type *newType = formalType->clone();
    339                                 alt.env.apply( newType );
    340                                 *actualExpr = new CastExpr( *actualExpr, newType );
    341                         }
    342                         convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) );
     375                        convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
    343376                        ++formal; // can't be in for-loop update because of the continue
    344377                }
     
    348381
    349382                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    350                         PRINT(
    351                                 std::cerr << std::endl << "converting ";
    352                                 assert->second.actualType->print( std::cerr, 8 );
    353                                 std::cerr << std::endl << " to ";
    354                                 assert->second.formalType->print( std::cerr, 8 );
    355                         )
    356                         Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    357                         PRINT(
    358                                 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
    359                         )
    360                         if ( newCost == Cost::infinity ) {
    361                                 return newCost;
    362                         }
    363                         convCost += newCost;
    364                         convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) );
     383                        convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    365384                }
    366385
     
    776795                // compute conversionsion costs
    777796                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    778                         Cost cvtCost = computeConversionCost( *withFunc, indexer );
     797                        Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
    779798
    780799                        PRINT(
     
    895914                                // count one safe conversion for each value that is thrown away
    896915                                thisCost.incSafe( discardedValues );
    897 
    898                                 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
     916                                Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
     917                                // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
     918                                // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
     919
     920                                // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
     921                                candidates.emplace_back( std::move( newAlt ) );
    899922                        } // if
    900923                } // for
     
    9791002        void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
    9801003                if ( sizeofExpr->get_isType() ) {
    981                         // xxx - resolveTypeof?
    982                         alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
     1004                        Type * newType = sizeofExpr->get_type()->clone();
     1005                        alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
    9831006                } else {
    9841007                        // find all alternatives for the argument to sizeof
     
    10001023        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
    10011024                if ( alignofExpr->get_isType() ) {
    1002                         // xxx - resolveTypeof?
    1003                         alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
     1025                        Type * newType = alignofExpr->get_type()->clone();
     1026                        alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
    10041027                } else {
    10051028                        // find all alternatives for the argument to sizeof
     
    11391162                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    11401163                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
     1164                                                // convert both options to the conditional result type
     1165                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
     1166                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    11411167                                                newAlt.expr = newExpr;
    11421168                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
Note: See TracChangeset for help on using the changeset viewer.