Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r435e75f r6013bd7  
    1414//
    1515
    16 #include <iostream>
    17 
     16#include "Resolver.h"
     17#include "AlternativeFinder.h"
    1818#include "Alternative.h"
    19 #include "AlternativeFinder.h"
    20 #include "CurrentObject.h"
    2119#include "RenameVars.h"
    22 #include "Resolver.h"
    2320#include "ResolveTypeof.h"
    2421#include "typeops.h"
    25 
     22#include "SynTree/Statement.h"
     23#include "SynTree/Type.h"
    2624#include "SynTree/Expression.h"
    2725#include "SynTree/Initializer.h"
    28 #include "SynTree/Statement.h"
    29 #include "SynTree/Type.h"
    30 
     26#include "SymTab/Indexer.h"
    3127#include "SymTab/Autogen.h"
    32 #include "SymTab/Indexer.h"
    33 
    3428#include "Common/utility.h"
    35 
    3629#include "InitTweak/InitTweak.h"
    3730
     31#include <iostream>
    3832using namespace std;
    3933
     
    4539                        if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
    4640                                functionReturn = res->functionReturn;
    47                                 currentObject = res->currentObject;
     41                                initContext = res->initContext;
    4842                                inEnumDecl = res->inEnumDecl;
    4943                        }
     
    8579
    8680                Type * functionReturn = nullptr;
    87                 CurrentObject currentObject = nullptr;
     81                Type *initContext = nullptr;
    8882                bool inEnumDecl = false;
    8983        };
     
    130124                        } // if
    131125#endif
    132                         assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
     126                        assert( finder.get_alternatives().size() == 1 );
    133127                        Alternative &choice = finder.get_alternatives().front();
    134128                        Expression *newExpr = choice.expr->clone();
     
    192186                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    193187                // the RHS.
    194                 ValueGuard<CurrentObject> temp( currentObject );
    195                 currentObject = CurrentObject( objectDecl->get_type() );
    196                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     188                Type *temp = initContext;
     189                initContext = new_type;
     190                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
    197191                        // enumerator initializers should not use the enum type to initialize, since
    198192                        // the enum type is still incomplete at this point. Use signed int instead.
    199                         currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     193                        initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
    200194                }
    201195                Parent::visit( objectDecl );
    202                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     196                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
    203197                        // delete newly created signed int type
    204                         // delete currentObject.getType();
    205                 }
     198                        delete initContext;
     199                }
     200                initContext = temp;
    206201        }
    207202
     
    320315
    321316        void Resolver::visit( SwitchStmt *switchStmt ) {
    322                 ValueGuard< CurrentObject > oldCurrentObject( currentObject );
     317                ValueGuard< Type * > oldInitContext( initContext );
    323318                Expression *newExpr;
    324319                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     
    326321                switchStmt->set_condition( newExpr );
    327322
    328                 currentObject = CurrentObject( newExpr->get_result() );
     323                initContext = newExpr->get_result();
    329324                Parent::visit( switchStmt );
    330325        }
     
    332327        void Resolver::visit( CaseStmt *caseStmt ) {
    333328                if ( caseStmt->get_condition() ) {
    334                         std::list< InitAlternative > initAlts = currentObject.getOptions();
    335                         assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    336                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
     329                        assert( initContext );
     330                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() );
    337331                        Expression * newExpr = findSingleExpression( castExpr, *this );
    338332                        castExpr = safe_dynamic_cast< CastExpr * >( newExpr );
     
    376370
    377371        void Resolver::visit( SingleInit *singleInit ) {
    378                 // resolve initialization using the possibilities as determined by the currentObject cursor
    379                 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    380                 Expression * newExpr = findSingleExpression( untyped, *this );
    381                 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
    382 
    383                 // move cursor to the object that is actually initialized
    384                 currentObject.setNext( initExpr->get_designation() );
    385 
    386                 // discard InitExpr wrapper and retain relevant pieces
    387                 newExpr = initExpr->get_expr();
    388                 newExpr->set_env( initExpr->get_env() );
    389                 initExpr->set_expr( nullptr );
    390                 initExpr->set_env( nullptr );
    391                 delete initExpr;
    392 
    393                 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
    394                 Type * initContext = currentObject.getCurrentType();
    395 
    396                 // check if actual object's type is char[]
    397                 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    398                         if ( isCharType( at->get_base() ) ) {
    399                                 // check if the resolved type is char *
    400                                 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    401                                         if ( isCharType( pt->get_base() ) ) {
    402                                                 // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    403                                                 CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr );
    404                                                 newExpr = ce->get_arg();
    405                                                 ce->set_arg( nullptr );
    406                                                 delete ce;
     372                if ( singleInit->get_value() ) {
     373                        // // find all the d's
     374                        // std::list<Expression *> &designators = singleInit->get_designators();
     375                        // std::list<Type *> types1{ initContext }, types2;
     376                        // for ( Expression * expr: designators ) {
     377                        //      cerr << expr << endl;
     378                        //      if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) {
     379                        //              for ( Type * type: types1 ) {
     380                        //                      cerr << type << endl;
     381                        //                      ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type);
     382                        //                      std::list<Declaration *> members;
     383                        //                      if ( fred ) {
     384                        //                              fred->lookup( nexpr->get_name(), members ); // concatenate identical field name
     385                        //                              for ( Declaration * mem: members ) {
     386                        //                                      if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) {
     387                        //                                              types2.push_back( dwt->get_type() );
     388                        //                                      } // if
     389                        //                              } // for
     390                        //                      } // if
     391                        //              } // for
     392                        //              types1 = types2;
     393                        //              types2.clear();
     394                        //      } // if
     395                        // } // for
     396                        // // for ( Type * type: types1 ) {
     397                        // //   cerr << type << endl;
     398                        // // } // for
     399                       
     400                        // // O(N^2) checks of d-types with f-types
     401                        // // find the minimum cost
     402                        CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
     403                        Expression *newExpr = findSingleExpression( castExpr, *this );
     404                        delete castExpr;
     405                        singleInit->set_value( newExpr );
     406
     407                        // check if initializing type is char[]
     408                        if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     409                                if ( isCharType( at->get_base() ) ) {
     410                                        // check if the resolved type is char *
     411                                        if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
     412                                                if ( isCharType( pt->get_base() ) ) {
     413                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     414                                                        CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
     415                                                        singleInit->set_value( ce->get_arg() );
     416                                                        ce->set_arg( NULL );
     417                                                        delete ce;
     418                                                }
    407419                                        }
    408420                                }
    409421                        }
    410                 }
    411 
    412                 // set initializer expr to resolved express
    413                 singleInit->set_value( newExpr );
    414 
    415                 // move cursor to next object in preparation for next initializer
    416                 currentObject.increment();
     422                } // if
     423        }
     424
     425        template< typename AggrInst >
     426        TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
     427                assert( inst );
     428                assert( inst->get_baseParameters() );
     429                std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
     430                std::list< Expression * > typeSubs = inst->get_parameters();
     431                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
     432                return subs;
     433        }
     434
     435        ReferenceToType * isStructOrUnion( Type * type ) {
     436                if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
     437                        return sit;
     438                } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
     439                        return uit;
     440                }
     441                return nullptr;
     442        }
     443
     444        void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
     445                DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
     446                assert( dt );
     447                // need to substitute for generic types, so that casts are to concrete types
     448                initContext = dt->get_type()->clone();
     449                sub.apply( initContext );
     450
     451                try {
     452                        if ( init == initEnd ) return; // stop when there are no more initializers
     453                        (*init)->accept( *this );
     454                        ++init; // made it past an initializer
     455                } catch( SemanticError & ) {
     456                        // need to delve deeper, if you can
     457                        if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
     458                                resolveAggrInit( type, init, initEnd );
     459                        } else {
     460                                // member is not an aggregate type, so can't go any deeper
     461
     462                                // might need to rethink what is being thrown
     463                                throw;
     464                        } // if
     465                }
     466        }
     467
     468        void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
     469                if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
     470                        TypeSubstitution sub = makeGenericSubstitutuion( sit );
     471                        StructDecl * st = sit->get_baseStruct();
     472                        if(st->get_members().empty()) return;
     473                        // want to resolve each initializer to the members of the struct,
     474                        // but if there are more initializers than members we should stop
     475                        list< Declaration * >::iterator it = st->get_members().begin();
     476                        for ( ; it != st->get_members().end(); ++it) {
     477                                resolveSingleAggrInit( *it, init, initEnd, sub );
     478                        }
     479                } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
     480                        TypeSubstitution sub = makeGenericSubstitutuion( uit );
     481                        UnionDecl * un = uit->get_baseUnion();
     482                        if(un->get_members().empty()) return;
     483                        // only resolve to the first member of a union
     484                        resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
     485                } // if
    417486        }
    418487
    419488        void Resolver::visit( ListInit * listInit ) {
    420                 // move cursor into brace-enclosed initializer-list
    421                 currentObject.enterListInit();
    422                 // xxx - fix this so that the list isn't copied, iterator should be used to change current element
    423                 std::list<Designation *> newDesignations;
    424                 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
    425                         // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
    426                         // the initializer against that object.
    427                         Designation * des = std::get<0>(p);
    428                         Initializer * init = std::get<1>(p);
    429                         newDesignations.push_back( currentObject.findNext( des ) );
    430                         init->accept( *this );
    431                 }
    432                 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
    433                 listInit->get_designations() = newDesignations; // xxx - memory management
    434                 currentObject.exitListInit();
    435 
    436                 // xxx - this part has not be folded into CurrentObject yet
    437                 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    438                 //      Type * base = tt->get_baseType()->get_base();
    439                 //      if ( base ) {
    440                 //              // know the implementation type, so try using that as the initContext
    441                 //              ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
    442                 //              currentObject = &tmpObj;
    443                 //              visit( listInit );
    444                 //      } else {
    445                 //              // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
    446                 //              Parent::visit( listInit );
    447                 //      }
    448                 // } else {
     489                InitIterator iter = listInit->begin();
     490                InitIterator end = listInit->end();
     491
     492                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     493                        // resolve each member to the base type of the array
     494                        for ( ; iter != end; ++iter ) {
     495                                initContext = at->get_base();
     496                                (*iter)->accept( *this );
     497                        } // for
     498                } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) {
     499                        for ( Type * t : *tt ) {
     500                                if ( iter == end ) break;
     501                                initContext = t;
     502                                (*iter++)->accept( *this );
     503                        }
     504                } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
     505                        resolveAggrInit( type, iter, end );
     506                } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     507                        Type * base = tt->get_baseType()->get_base();
     508                        if ( base ) {
     509                                // know the implementation type, so try using that as the initContext
     510                                initContext = base;
     511                                visit( listInit );
     512                        } else {
     513                                // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     514                                Parent::visit( listInit );
     515                        }
     516                } else {
     517                        assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
     518                                || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) );
     519                        // basic types are handled here
     520                        Parent::visit( listInit );
     521                }
     522
     523#if 0
     524                if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
     525                        std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
     526                        for ( ; iter != listInit->end_initializers(); ++iter ) {
     527                                initContext = at->get_base();
     528                                (*iter)->accept( *this );
     529                        } // for
     530                } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
     531                        StructDecl *baseStruct = st->get_baseStruct();
     532                        std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
     533                        std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
     534                        for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
     535                                if ( (*iter2)->get_designators().empty() ) {
     536                                        DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
     537                                        initContext = dt->get_type();
     538                                        (*iter2)->accept( *this );
     539                                        ++iter1;
     540                                } else {
     541                                        StructDecl *st = baseStruct;
     542                                        iter1 = st->get_members().begin();
     543                                        std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
     544                                        for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
     545                                                NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
     546                                                assert( key );
     547                                                for ( ; iter1 != st->get_members().end(); ++iter1 ) {
     548                                                        if ( key->get_name() == (*iter1)->get_name() ) {
     549                                                                (*iter1)->print( cout );
     550                                                                cout << key->get_name() << endl;
     551                                                                ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
     552                                                                assert( fred );
     553                                                                StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
     554                                                                assert( mary );
     555                                                                st = mary->get_baseStruct();
     556                                                                iter1 = st->get_members().begin();
     557                                                                break;
     558                                                        } // if
     559                                                }  // for
     560                                        } // for
     561                                        ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
     562                                        assert( fred );
     563                                        initContext = fred->get_type();
     564                                        (*listInit->begin_initializers())->accept( *this );
     565                                } // if
     566                        } // for
     567                } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
     568                        DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
     569                        initContext = dt->get_type();
     570                        (*listInit->begin_initializers())->accept( *this );
     571                } // if
     572#endif
    449573        }
    450574
Note: See TracChangeset for help on using the changeset viewer.