Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    re4d829b r0b150ec  
    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        };
     
    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 );
     
    375369        }
    376370
    377         template< typename Aggr >
    378         void lookupDesignation( Aggr * aggr, const std::list< Expression > & designators ) {
    379 
    380         }
    381 
    382371        void Resolver::visit( SingleInit *singleInit ) {
    383                 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    384                 Expression * newExpr = findSingleExpression( untyped, *this );
    385                 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
    386                 singleInit->set_value( new CastExpr( initExpr->get_expr()->clone(), initExpr->get_result()->clone() ) );
    387                 currentObject.setNext( initExpr->get_designation() );
    388                 currentObject.increment();
    389                 delete initExpr;
    390 
    391                 // // check if initializing type is char[]
    392                 // if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    393                 //      if ( isCharType( at->get_base() ) ) {
    394                 //              // check if the resolved type is char *
    395                 //              if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    396                 //                      if ( isCharType( pt->get_base() ) ) {
    397                 //                              // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    398                 //                              CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
    399                 //                              singleInit->set_value( ce->get_arg() );
    400                 //                              ce->set_arg( NULL );
    401                 //                              delete ce;
    402                 //                      }
    403                 //              }
    404                 //      }
    405                 // }
    406         }
    407 
    408         // template< typename AggrInst >
    409         // TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
    410         //      assert( inst );
    411         //      assert( inst->get_baseParameters() );
    412         //      std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
    413         //      std::list< Expression * > typeSubs = inst->get_parameters();
    414         //      TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    415         //      return subs;
    416         // }
    417 
    418         // ReferenceToType * isStructOrUnion( Type * type ) {
    419         //      if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
    420         //              return sit;
    421         //      } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
    422         //              return uit;
    423         //      }
    424         //      return nullptr;
    425         // }
    426 
    427         // void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
    428         //      ObjectDecl * obj = dynamic_cast< ObjectDecl * >( dcl );
    429         //      assert( obj );
    430         //      // need to substitute for generic types, so that casts are to concrete types
    431         //      currentObject = obj->clone();  // xxx - delete this
    432         //      sub.apply( currentObject );
    433 
    434         //      try {
    435         //              if ( init == initEnd ) return; // stop when there are no more initializers
    436         //              (*init)->accept( *this );
    437         //              ++init; // made it past an initializer
    438         //      } catch( SemanticError & ) {
    439         //              // need to delve deeper, if you can
    440         //              if ( ReferenceToType * type = isStructOrUnion( currentObject->get_type() ) ) {
    441         //                      resolveAggrInit( type, init, initEnd );
    442         //              } else {
    443         //                      // member is not an aggregate type, so can't go any deeper
    444 
    445         //                      // might need to rethink what is being thrown
    446         //                      throw;
    447         //              } // if
    448         //      }
    449         // }
    450 
    451         // void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
    452         //      if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
    453         //              TypeSubstitution sub = makeGenericSubstitution( sit );
    454         //              StructDecl * st = sit->get_baseStruct();
    455         //              if(st->get_members().empty()) return;
    456         //              // want to resolve each initializer to the members of the struct,
    457         //              // but if there are more initializers than members we should stop
    458         //              list< Declaration * >::iterator it = st->get_members().begin();
    459         //              for ( ; it != st->get_members().end(); ++it) {
    460         //                      resolveSingleAggrInit( *it, init, initEnd, sub );
    461         //              }
    462         //      } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
    463         //              TypeSubstitution sub = makeGenericSubstitution( uit );
    464         //              UnionDecl * un = uit->get_baseUnion();
    465         //              if(un->get_members().empty()) return;
    466         //              // only resolve to the first member of a union
    467         //              resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
    468         //      } // if
    469         // }
     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                                                }
     419                                        }
     420                                }
     421                        }
     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
     486        }
    470487
    471488        void Resolver::visit( ListInit * listInit ) {
    472                 currentObject.enterListInit();
    473                 // xxx - fix this so that the list isn't copied, iterator should be used to change current element
    474                 std::list<Designation *> newDesignations;
    475                 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
    476                         Designation * des = std::get<0>(p);
    477                         Initializer * init = std::get<1>(p);
    478                         newDesignations.push_back( currentObject.findNext( des ) );
    479                         init->accept( *this );
    480                 }
    481                 listInit->get_designations() = newDesignations; // xxx - memory management
    482                 currentObject.exitListInit();
    483 
    484                 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    485                 //      Type * base = tt->get_baseType()->get_base();
    486                 //      if ( base ) {
    487                 //              // know the implementation type, so try using that as the initContext
    488                 //              ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
    489                 //              currentObject = &tmpObj;
    490                 //              visit( listInit );
    491                 //      } else {
    492                 //              // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
    493                 //              Parent::visit( listInit );
    494                 //      }
    495                 // } 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
    496573        }
    497574
Note: See TracChangeset for help on using the changeset viewer.