Ignore:
Timestamp:
Oct 19, 2017, 12:01:04 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
837ce06
Parents:
b96ec83 (diff), a15b72c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rb96ec83 r6840e7c  
    5353                void previsit( FunctionDecl *functionDecl );
    5454                void postvisit( FunctionDecl *functionDecl );
    55                 void previsit( ObjectDecl *functionDecl );
     55                void previsit( ObjectDecl *objectDecll );
    5656                void previsit( TypeDecl *typeDecl );
    5757                void previsit( EnumDecl * enumDecl );
     
    109109
    110110        namespace {
    111                 void finishExpr( Expression *expr, const TypeEnvironment &env ) {
    112                         expr->set_env( new TypeSubstitution );
     111                void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     112                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    113113                        env.makeSubstitution( *expr->get_env() );
    114114                }
     115
     116                void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) {
     117                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     118                                if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
     119                                        // cast is to the same type as its argument, so it's unnecessary -- remove it
     120                                        expr = castExpr->arg;
     121                                        castExpr->arg = nullptr;
     122                                        std::swap( expr->env, castExpr->env );
     123                                        delete castExpr;
     124                                }
     125                        }
     126                }
    115127        } // namespace
    116128
    117         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     129        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    118130                global_renamer.reset();
    119131                TypeEnvironment env;
    120132                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    121                 finishExpr( newExpr, env );
    122                 return newExpr;
    123         }
    124 
    125         Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     133                finishExpr( newExpr, env, untyped->env );
     134                delete untyped;
     135                untyped = newExpr;
     136        }
     137
     138        void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {
     139                if ( ! untyped ) return;
    126140                TypeEnvironment env;
    127141                AlternativeFinder finder( indexer, env );
     
    129143                #if 0
    130144                if ( finder.get_alternatives().size() != 1 ) {
    131                         std::cout << "untyped expr is ";
    132                         untyped->print( std::cout );
    133                         std::cout << std::endl << "alternatives are:";
    134                         for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    135                                 i->print( std::cout );
     145                        std::cerr << "untyped expr is ";
     146                        untyped->print( std::cerr );
     147                        std::cerr << std::endl << "alternatives are:";
     148                        for ( const Alternative & alt : finder.get_alternatives() ) {
     149                                alt.print( std::cerr );
    136150                        } // for
    137151                } // if
     
    140154                Alternative &choice = finder.get_alternatives().front();
    141155                Expression *newExpr = choice.expr->clone();
    142                 finishExpr( newExpr, choice.env );
    143                 return newExpr;
     156                finishExpr( newExpr, choice.env, untyped->env );
     157                delete untyped;
     158                untyped = newExpr;
     159        }
     160
     161        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
     162                assert( untyped && type );
     163                untyped = new CastExpr( untyped, type );
     164                findSingleExpression( untyped, indexer );
     165                removeExtraneousCast( untyped, indexer );
    144166        }
    145167
     
    157179                }
    158180
    159                 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     181                void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    160182                        TypeEnvironment env;
    161183                        AlternativeFinder finder( indexer, env );
     
    186208                                throw SemanticError( "No interpretations for case control expression", untyped );
    187209                        } // if
    188                         finishExpr( newExpr, *newEnv );
    189                         return newExpr;
     210                        finishExpr( newExpr, *newEnv, untyped->env );
     211                        delete untyped;
     212                        untyped = newExpr;
    190213                }
    191214
     
    212235        void Resolver::handlePtrType( PtrType * type ) {
    213236                if ( type->get_dimension() ) {
    214                         CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    215                         Expression *newExpr = findSingleExpression( castExpr, indexer );
    216                         delete type->get_dimension();
    217                         type->set_dimension( newExpr );
     237                        findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
    218238                }
    219239        }
     
    245265                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    246266        }
    247 
    248267
    249268        void Resolver::postvisit( FunctionDecl *functionDecl ) {
     
    269288        void Resolver::previsit( ExprStmt *exprStmt ) {
    270289                visit_children = false;
    271                 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    272                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
    273                 delete exprStmt->get_expr();
    274                 exprStmt->set_expr( newExpr );
     290                assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
     291                findVoidExpression( exprStmt->expr, indexer );
    275292        }
    276293
    277294        void Resolver::previsit( AsmExpr *asmExpr ) {
    278295                visit_children = false;
    279                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
    280                 delete asmExpr->get_operand();
    281                 asmExpr->set_operand( newExpr );
     296                findVoidExpression( asmExpr->operand, indexer );
    282297                if ( asmExpr->get_inout() ) {
    283                         newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
    284                         delete asmExpr->get_inout();
    285                         asmExpr->set_inout( newExpr );
     298                        findVoidExpression( asmExpr->inout, indexer );
    286299                } // if
    287300        }
     
    294307
    295308        void Resolver::previsit( IfStmt *ifStmt ) {
    296                 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
    297                 delete ifStmt->get_condition();
    298                 ifStmt->set_condition( newExpr );
     309                findSingleExpression( ifStmt->condition, indexer );
    299310        }
    300311
    301312        void Resolver::previsit( WhileStmt *whileStmt ) {
    302                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
    303                 delete whileStmt->get_condition();
    304                 whileStmt->set_condition( newExpr );
     313                findSingleExpression( whileStmt->condition, indexer );
    305314        }
    306315
    307316        void Resolver::previsit( ForStmt *forStmt ) {
    308                 if ( forStmt->get_condition() ) {
    309                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
    310                         delete forStmt->get_condition();
    311                         forStmt->set_condition( newExpr );
     317                if ( forStmt->condition ) {
     318                        findSingleExpression( forStmt->condition, indexer );
    312319                } // if
    313320
    314                 if ( forStmt->get_increment() ) {
    315                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
    316                         delete forStmt->get_increment();
    317                         forStmt->set_increment( newExpr );
     321                if ( forStmt->increment ) {
     322                        findVoidExpression( forStmt->increment, indexer );
    318323                } // if
    319324        }
     
    321326        void Resolver::previsit( SwitchStmt *switchStmt ) {
    322327                GuardValue( currentObject );
    323                 Expression *newExpr;
    324                 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
    325                 delete switchStmt->get_condition();
    326                 switchStmt->set_condition( newExpr );
    327 
    328                 currentObject = CurrentObject( newExpr->get_result() );
     328                findIntegralExpression( switchStmt->condition, indexer );
     329
     330                currentObject = CurrentObject( switchStmt->condition->result );
    329331        }
    330332
     
    333335                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    334336                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    335                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    336                         Expression * newExpr = findSingleExpression( castExpr, indexer );
    337                         castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    338                         caseStmt->set_condition( castExpr->get_arg() );
    339                         castExpr->set_arg( nullptr );
     337                        // must remove cast from case statement because RangeExpr cannot be cast.
     338                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
     339                        findSingleExpression( newExpr, indexer );
     340                        CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
     341                        caseStmt->condition = castExpr->arg;
     342                        castExpr->arg = nullptr;
    340343                        delete castExpr;
    341344                }
     
    346349                // must resolve the argument for a computed goto
    347350                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
    348                         if ( Expression * arg = branchStmt->get_computedTarget() ) {
    349                                 VoidType v = Type::Qualifiers();                // cast to void * for the alternative finder
    350                                 PointerType pt( Type::Qualifiers(), v.clone() );
    351                                 CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    352                                 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
    353                                 branchStmt->set_target( newExpr );
     351                        if ( branchStmt->computedTarget ) {
     352                                // computed goto argument is void *
     353                                findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer );
    354354                        } // if
    355355                } // if
     
    358358        void Resolver::previsit( ReturnStmt *returnStmt ) {
    359359                visit_children = false;
    360                 if ( returnStmt->get_expr() ) {
    361                         CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    362                         Expression *newExpr = findSingleExpression( castExpr, indexer );
    363                         delete castExpr;
    364                         returnStmt->set_expr( newExpr );
     360                if ( returnStmt->expr ) {
     361                        findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer );
    365362                } // if
    366363        }
     
    373370                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    374371                        assert( exception_decl );
    375                         Expression * wrapped = new CastExpr(
    376                                 throwStmt->get_expr(),
    377                                 new PointerType(
    378                                         noQualifiers,
    379                                         new StructInstType(
    380                                                 noQualifiers,
    381                                                 exception_decl
    382                                                 )
    383                                         )
    384                                 );
    385                         Expression * newExpr = findSingleExpression( wrapped, indexer );
    386                         throwStmt->set_expr( newExpr );
     372                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     373                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    387374                }
    388375        }
    389376
    390377        void Resolver::previsit( CatchStmt *catchStmt ) {
    391                 if ( catchStmt->get_cond() ) {
    392                         Expression * wrapped = new CastExpr(
    393                                 catchStmt->get_cond(),
    394                                 new BasicType( noQualifiers, BasicType::Bool )
    395                                 );
    396                         catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
    397                 }
    398         }
    399 
    400         inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {
    401                 if( !expr ) return;
    402                 Expression * newExpr = findSingleExpression( expr, indexer );
    403                 delete expr;
    404                 expr = newExpr;
    405         }
    406 
    407         inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {
    408                 if( !expr ) return;
    409                 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );
    410                 delete expr;
    411                 expr = newExpr;
     378                if ( catchStmt->cond ) {
     379                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     380                }
    412381        }
    413382
     
    579548                        // Resolve the conditions as if it were an IfStmt
    580549                        // Resolve the statments normally
    581                         resolveAsIf( clause.condition, this->indexer );
     550                        findSingleExpression( clause.condition, this->indexer );
    582551                        clause.statement->accept( *visitor );
    583552                }
     
    588557                        // Resolve the conditions as if it were an IfStmt
    589558                        // Resolve the statments normally
    590                         resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
    591                         resolveAsIf  ( stmt->timeout.condition, this->indexer );
     559                        findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
     560                        findSingleExpression( stmt->timeout.condition, this->indexer );
    592561                        stmt->timeout.statement->accept( *visitor );
    593562                }
     
    596565                        // Resolve the conditions as if it were an IfStmt
    597566                        // Resolve the statments normally
    598                         resolveAsIf( stmt->orelse.condition, this->indexer );
     567                        findSingleExpression( stmt->orelse.condition, this->indexer );
    599568                        stmt->orelse.statement->accept( *visitor );
    600569                }
     
    613582                visit_children = false;
    614583                // resolve initialization using the possibilities as determined by the currentObject cursor
    615                 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    616                 Expression * newExpr = findSingleExpression( untyped, indexer );
     584                Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() );
     585                findSingleExpression( newExpr, indexer );
    617586                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    618587
     
    621590
    622591                // discard InitExpr wrapper and retain relevant pieces
    623                 newExpr = initExpr->get_expr();
    624                 newExpr->set_env( initExpr->get_env() );
    625                 initExpr->set_expr( nullptr );
    626                 initExpr->set_env( nullptr );
     592                newExpr = initExpr->expr;
     593                initExpr->expr = nullptr;
     594                std::swap( initExpr->env, newExpr->env );
    627595                delete initExpr;
    628596
    629597                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
    630598                Type * initContext = currentObject.getCurrentType();
     599
     600                removeExtraneousCast( newExpr, indexer );
    631601
    632602                // check if actual object's type is char[]
     
    636606                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    637607                                        if ( isCharType( pt->get_base() ) ) {
    638                                                 // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    639                                                 CastExpr *ce = strict_dynamic_cast< CastExpr * >( newExpr );
    640                                                 newExpr = ce->get_arg();
    641                                                 ce->set_arg( nullptr );
    642                                                 delete ce;
     608                                                if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) {
     609                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     610                                                        newExpr = ce->get_arg();
     611                                                        ce->set_arg( nullptr );
     612                                                        std::swap( ce->env, newExpr->env );
     613                                                        delete ce;
     614                                                }
    643615                                        }
    644616                                }
     
    647619
    648620                // set initializer expr to resolved express
    649                 singleInit->set_value( newExpr );
     621                singleInit->value = newExpr;
    650622
    651623                // move cursor to next object in preparation for next initializer
Note: See TracChangeset for help on using the changeset viewer.