Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r8c84ebd r8e9cbb2  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AlternativeFinder.cc -- 
     7// AlternativeFinder.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  3 17:58:39 2015
    13 // Update Count     : 22
     12// Last Modified On : Mon Jul  4 17:02:51 2016
     13// Update Count     : 29
    1414//
    1515
     
    1919#include <functional>
    2020#include <cassert>
     21#include <unordered_map>
     22#include <utility>
     23#include <vector>
    2124
    2225#include "AlternativeFinder.h"
     
    3841#include "Tuples/TupleAssignment.h"
    3942#include "Tuples/NameMatcher.h"
    40 #include "utility.h"
     43#include "Common/utility.h"
     44#include "InitTweak/InitTweak.h"
    4145
    4246extern bool resolvep;
    43 #define PRINT( text ) if ( resolvep ) { text } 
     47#define PRINT( text ) if ( resolvep ) { text }
    4448//#define DEBUG_COST
    4549
     
    107111                                        if ( candidate->cost < mapPlace->second.candidate->cost ) {
    108112                                                PRINT(
    109                                                         std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
     113                                                        std::cerr << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
    110114                                                )
    111115                                                selected[ mangleName ] = current;
    112116                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    113117                                                PRINT(
    114                                                         std::cout << "marking ambiguous" << std::endl;
     118                                                        std::cerr << "marking ambiguous" << std::endl;
    115119                                                )
    116120                                                mapPlace->second.isAmbiguous = true;
     
    122126
    123127                        PRINT(
    124                                 std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
     128                                std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl;
    125129                        )
    126130
     
    182186                        begin++;
    183187                        PRINT(
    184                                 std::cout << "findSubExprs" << std::endl;
    185                                 printAlts( finder.alternatives, std::cout );
     188                                std::cerr << "findSubExprs" << std::endl;
     189                                printAlts( finder.alternatives, std::cerr );
    186190                        )
    187191                        *out++ = finder;
     
    204208                }
    205209                PRINT(
    206                         std::cout << "alternatives before prune:" << std::endl;
    207                         printAlts( alternatives, std::cout );
     210                        std::cerr << "alternatives before prune:" << std::endl;
     211                        printAlts( alternatives, std::cerr );
    208212                )
    209213                AltList::iterator oldBegin = alternatives.begin();
     
    221225                alternatives.erase( oldBegin, alternatives.end() );
    222226                PRINT(
    223                         std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
     227                        std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
    224228                )
     229
     230                // Central location to handle gcc extension keyword for all expression types.
     231                for ( Alternative &iter: alternatives ) {
     232                        iter.expr->set_extension( expr->get_extension() );
     233                } // for
    225234        }
    226235
     
    261270                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    262271                        PRINT(
    263                                 std::cout << "actual expression:" << std::endl;
    264                                 (*actualExpr)->print( std::cout, 8 );
    265                                 std::cout << "--- results are" << std::endl;
    266                                 printAll( (*actualExpr)->get_results(), std::cout, 8 );
     272                                std::cerr << "actual expression:" << std::endl;
     273                                (*actualExpr)->print( std::cerr, 8 );
     274                                std::cerr << "--- results are" << std::endl;
     275                                printAll( (*actualExpr)->get_results(), std::cerr, 8 );
    267276                        )
    268277                        std::list< DeclarationWithType* >::iterator startFormal = formal;
     
    278287                                }
    279288                                PRINT(
    280                                         std::cout << std::endl << "converting ";
    281                                         (*actual)->print( std::cout, 8 );
    282                                         std::cout << std::endl << " to ";
    283                                         (*formal)->get_type()->print( std::cout, 8 );
     289                                        std::cerr << std::endl << "converting ";
     290                                        (*actual)->print( std::cerr, 8 );
     291                                        std::cerr << std::endl << " to ";
     292                                        (*formal)->get_type()->print( std::cerr, 8 );
    284293                                )
    285294                                Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    286295                                PRINT(
    287                                         std::cout << std::endl << "cost is" << newCost << std::endl;
     296                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
    288297                                )
    289298
     
    323332                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    324333                        PRINT(
    325                                 std::cout << std::endl << "converting ";
    326                                 assert->second.actualType->print( std::cout, 8 );
    327                                 std::cout << std::endl << " to ";
    328                                 assert->second.formalType->print( std::cout, 8 );
     334                                std::cerr << std::endl << "converting ";
     335                                assert->second.actualType->print( std::cerr, 8 );
     336                                std::cerr << std::endl << " to ";
     337                                assert->second.formalType->print( std::cerr, 8 );
    329338                                )
    330339                                Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    331340                        PRINT(
    332                                 std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
     341                                std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
    333342                                )
    334343                                if ( newCost == Cost::infinity ) {
     
    407416        }
    408417
    409         static const int recursionLimit = 10;
     418        // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included
     419        //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;
     420       
     421        static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
     422        //static const unsigned recursionParentLimit = 1;  ///< Limit to the number of times an assertion can recursively use itself
    410423
    411424        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     
    416429                }
    417430        }
    418 
     431       
    419432        template< typename ForwardIterator, typename OutputIterator >
    420         void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
     433        void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/
     434                                                 int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    421435                if ( begin == end ) {
    422436                        if ( newNeed.empty() ) {
     
    431445                                        printAssertionSet( newNeed, std::cerr, 8 );
    432446                                )
    433                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     447                                inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out );
    434448                                return;
    435449                        }
     
    438452                ForwardIterator cur = begin++;
    439453                if ( ! cur->second ) {
    440                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     454                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    441455                }
    442456                DeclarationWithType *curDecl = cur->first;
     
    448462                std::list< DeclarationWithType* > candidates;
    449463                decls.lookupId( curDecl->get_name(), candidates );
    450 ///   if ( candidates.empty() ) { std::cout << "no candidates!" << std::endl; }
     464///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    451465                for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
    452466                        PRINT(
    453                                 std::cout << "inferRecursive: candidate is ";
    454                                 (*candidate)->print( std::cout );
    455                                 std::cout << std::endl;
     467                                std::cerr << "inferRecursive: candidate is ";
     468                                (*candidate)->print( std::cerr );
     469                                std::cerr << std::endl;
    456470                        )
     471                       
    457472                        AssertionSet newHave, newerNeed( newNeed );
    458473                        TypeEnvironment newEnv( newAlt.env );
     
    477492                                newerAlt.env = newEnv;
    478493                                assert( (*candidate)->get_uniqueId() );
    479                                 Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
     494                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
     495                                //AssertionParentSet newNeedParents( needParents );
     496                                // skip repeatingly-self-recursive assertion satisfaction
     497                                // DOESN'T WORK: grandchild nodes conflict with their cousins
     498                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
     499                                Expression *varExpr = new VariableExpr( candDecl );
    480500                                deleteAll( varExpr->get_results() );
    481501                                varExpr->get_results().clear();
    482502                                varExpr->get_results().push_front( adjType->clone() );
    483503                                PRINT(
    484                                         std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    485                                         curDecl->print( std::cout );
    486                                         std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
    487                                         (*candidate)->print( std::cout );
    488                                         std::cout << std::endl;
     504                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     505                                        curDecl->print( std::cerr );
     506                                        std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";
     507                                        (*candidate)->print( std::cerr );
     508                                        std::cerr << std::endl;
    489509                                )
    490510                                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    491511                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    492512                                appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    493                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     513                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    494514                        } else {
    495515                                delete adjType;
     
    501521        void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
    502522//      PRINT(
    503 //          std::cout << "inferParameters: assertions needed are" << std::endl;
    504 //          printAll( need, std::cout, 8 );
     523//          std::cerr << "inferParameters: assertions needed are" << std::endl;
     524//          printAll( need, std::cerr, 8 );
    505525//          )
    506526                SymTab::Indexer decls( indexer );
    507527                PRINT(
    508                         std::cout << "============= original indexer" << std::endl;
    509                         indexer.print( std::cout );
    510                         std::cout << "============= new indexer" << std::endl;
    511                         decls.print( std::cout );
     528                        std::cerr << "============= original indexer" << std::endl;
     529                        indexer.print( std::cerr );
     530                        std::cerr << "============= new indexer" << std::endl;
     531                        decls.print( std::cerr );
    512532                )
    513533                addToIndexer( have, decls );
    514534                AssertionSet newNeed;
    515                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     535                //AssertionParentSet needParents;
     536                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
    516537//      PRINT(
    517 //          std::cout << "declaration 14 is ";
     538//          std::cerr << "declaration 14 is ";
    518539//          Declaration::declFromId
    519540//          *out++ = newAlt;
     
    532553                        makeExprList( actualAlt, appExpr->get_args() );
    533554                        PRINT(
    534                                 std::cout << "need assertions:" << std::endl;
    535                                 printAssertionSet( resultNeed, std::cout, 8 );
     555                                std::cerr << "need assertions:" << std::endl;
     556                                printAssertionSet( resultNeed, std::cerr, 8 );
    536557                        )
    537558                        inferParameters( resultNeed, resultHave, newAlt, openVars, out );
     
    543564                AlternativeFinder funcOpFinder( indexer, env );
    544565
    545                 AlternativeFinder funcFinder( indexer, env ); {
    546                         NameExpr *fname = 0;;
    547                         if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
    548                                  && ( fname->get_name() == std::string("&&")) ) {
     566                AlternativeFinder funcFinder( indexer, env );
     567
     568                {
     569                        std::string fname = InitTweak::getFunctionName( untypedExpr );
     570                        if ( fname == "&&" ) {
    549571                                VoidType v = Type::Qualifiers();                // resolve to type void *
    550572                                PointerType pt( Type::Qualifiers(), v.clone() );
     
    570592
    571593                AltList candidates;
     594                SemanticError errors;
    572595
    573596                for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    574                         PRINT(
    575                                 std::cout << "working on alternative: " << std::endl;
    576                                 func->print( std::cout, 8 );
    577                         )
    578                         // check if the type is pointer to function
    579                         PointerType *pointer;
    580                         if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    581                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    582                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    583                                                 // XXX
    584                                                 //Designators::check_alternative( function, *actualAlt );
    585                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    586                                         }
    587                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    588                                         EqvClass eqvClass;
    589                                         if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    590                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    591                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    592                                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    593                                                         } // for
     597                        try {
     598                                PRINT(
     599                                        std::cerr << "working on alternative: " << std::endl;
     600                                        func->print( std::cerr, 8 );
     601                                )
     602                                // check if the type is pointer to function
     603                                PointerType *pointer;
     604                                if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     605                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     606                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     607                                                        // XXX
     608                                                        //Designators::check_alternative( function, *actualAlt );
     609                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     610                                                }
     611                                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
     612                                                EqvClass eqvClass;
     613                                                if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     614                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     615                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     616                                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     617                                                                } // for
     618                                                        } // if
    594619                                                } // if
    595620                                        } // if
     621                                } else {
     622                                        // seek a function operator that's compatible
     623                                        if ( ! doneInit ) {
     624                                                doneInit = true;
     625                                                NameExpr *opExpr = new NameExpr( "?()" );
     626                                                try {
     627                                                        funcOpFinder.findWithAdjustment( opExpr );
     628                                                } catch( SemanticError &e ) {
     629                                                        // it's ok if there aren't any defined function ops
     630                                                }
     631                                                PRINT(
     632                                                        std::cerr << "known function ops:" << std::endl;
     633                                                        printAlts( funcOpFinder.alternatives, std::cerr, 8 );
     634                                                )
     635                                        }
     636
     637                                        for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     638                                                // check if the type is pointer to function
     639                                                PointerType *pointer;
     640                                                if ( funcOp->expr->get_results().size() == 1
     641                                                        && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     642                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     643                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     644                                                                        AltList currentAlt;
     645                                                                        currentAlt.push_back( *func );
     646                                                                        currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
     647                                                                        makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     648                                                                } // for
     649                                                        } // if
     650                                                } // if
     651                                        } // for
    596652                                } // if
    597                         } else {
    598                                 // seek a function operator that's compatible
    599                                 if ( ! doneInit ) {
    600                                         doneInit = true;
    601                                         NameExpr *opExpr = new NameExpr( "?()" );
    602                                         try {
    603                                                 funcOpFinder.findWithAdjustment( opExpr );
    604                                         } catch( SemanticError &e ) {
    605                                                 // it's ok if there aren't any defined function ops
    606                                         }
    607                                         PRINT(
    608                                                 std::cout << "known function ops:" << std::endl;
    609                                                 printAlts( funcOpFinder.alternatives, std::cout, 8 );
    610                                         )
    611                                 }
    612 
    613                                 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    614                                         // check if the type is pointer to function
    615                                         PointerType *pointer;
    616                                         if ( funcOp->expr->get_results().size() == 1
    617                                                  && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    618                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    619                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    620                                                                 AltList currentAlt;
    621                                                                 currentAlt.push_back( *func );
    622                                                                 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    623                                                                 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    624                                                         } // for
    625                                                 } // if
    626                                         } // if
    627                                 } // for
    628                         } // if
    629                 } // for
     653                        } catch ( SemanticError &e ) {
     654                                errors.append( e );
     655                        }
     656                } // for
     657
     658                // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions
     659                if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; }
    630660
    631661                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
     
    639669                                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    640670                                assert( function );
    641                                 std::cout << "Case +++++++++++++" << std::endl;
    642                                 std::cout << "formals are:" << std::endl;
    643                                 printAll( function->get_parameters(), std::cout, 8 );
    644                                 std::cout << "actuals are:" << std::endl;
    645                                 printAll( appExpr->get_args(), std::cout, 8 );
    646                                 std::cout << "bindings are:" << std::endl;
    647                                 withFunc->env.print( std::cout, 8 );
    648                                 std::cout << "cost of conversion is:" << cvtCost << std::endl;
     671                                std::cerr << "Case +++++++++++++" << std::endl;
     672                                std::cerr << "formals are:" << std::endl;
     673                                printAll( function->get_parameters(), std::cerr, 8 );
     674                                std::cerr << "actuals are:" << std::endl;
     675                                printAll( appExpr->get_args(), std::cerr, 8 );
     676                                std::cerr << "bindings are:" << std::endl;
     677                                withFunc->env.print( std::cerr, 8 );
     678                                std::cerr << "cost of conversion is:" << cvtCost << std::endl;
    649679                        )
    650680                        if ( cvtCost != Cost::infinity ) {
     
    698728                        std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    699729                        std::advance( candidate_end, castExpr->get_results().size() );
     730                        // unification run for side-effects
     731                        unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
     732                                           (*i).expr->get_results().begin(), candidate_end,
     733                                   i->env, needAssertions, haveAssertions, openVars, indexer );
    700734                        Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    701                                                                                   castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
     735                                                                                  castExpr->get_results().begin(), castExpr->get_results().end(),
     736                                                                                  indexer, i->env );
    702737                        if ( thisCost != Cost::infinity ) {
    703738                                // count one safe conversion for each value that is thrown away
     
    787822        }
    788823
     824        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
     825                if ( alignofExpr->get_isType() ) {
     826                        alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
     827                } else {
     828                        // find all alternatives for the argument to sizeof
     829                        AlternativeFinder finder( indexer, env );
     830                        finder.find( alignofExpr->get_expr() );
     831                        // find the lowest cost alternative among the alternatives, otherwise ambiguous
     832                        AltList winners;
     833                        findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
     834                        if ( winners.size() != 1 ) {
     835                                throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
     836                        } // if
     837                        // return the lowest cost alternative for the argument
     838                        Alternative &choice = winners.front();
     839                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     840                } // if
     841        }
     842
     843        template< typename StructOrUnionType >
     844        void AlternativeFinder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {
     845                std::list< Declaration* > members;
     846                aggInst->lookup( name, members );
     847                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     848                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     849                                alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) );
     850                                renameTypes( alternatives.back().expr );
     851                        } else {
     852                                assert( false );
     853                        }
     854                }
     855        }
     856
     857        void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) {
     858                AlternativeFinder funcFinder( indexer, env );
     859                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( offsetofExpr->get_type() ) ) {
     860                        addOffsetof( structInst, offsetofExpr->get_member() );
     861                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( offsetofExpr->get_type() ) ) {
     862                        addOffsetof( unionInst, offsetofExpr->get_member() );
     863                }
     864        }
     865
     866        void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
     867                alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
     868        }
     869
     870        void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) {
     871                alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
     872        }
     873
    789874        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    790875                // assume no polymorphism
     
    792877                assert( function->get_parameters().size() == 1 );
    793878                PRINT(
    794                         std::cout << "resolvAttr: funcDecl is ";
    795                         funcDecl->print( std::cout );
    796                         std::cout << " argType is ";
    797                         argType->print( std::cout );
    798                         std::cout << std::endl;
     879                        std::cerr << "resolvAttr: funcDecl is ";
     880                        funcDecl->print( std::cerr );
     881                        std::cerr << " argType is ";
     882                        argType->print( std::cerr );
     883                        std::cerr << std::endl;
    799884                )
    800885                if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     
    9171002                } // for
    9181003        }
     1004
     1005        void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     1006                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     1007        }
    9191008} // namespace ResolvExpr
    9201009
Note: See TracChangeset for help on using the changeset viewer.