Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r3c398b6 r08da53d  
    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                }
    115115        } // namespace
    116116
    117         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     117        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    118118                global_renamer.reset();
    119119                TypeEnvironment env;
    120120                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    121                 finishExpr( newExpr, env );
    122                 return newExpr;
    123         }
    124 
    125         Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     121                finishExpr( newExpr, env, untyped->env );
     122                delete untyped;
     123                untyped = newExpr;
     124        }
     125
     126        void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {
     127                if ( ! untyped ) return;
    126128                TypeEnvironment env;
    127129                AlternativeFinder finder( indexer, env );
     
    129131                #if 0
    130132                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 );
     133                        std::cerr << "untyped expr is ";
     134                        untyped->print( std::cerr );
     135                        std::cerr << std::endl << "alternatives are:";
     136                        for ( const Alternative & alt : finder.get_alternatives() ) {
     137                                alt.print( std::cerr );
    136138                        } // for
    137139                } // if
     
    140142                Alternative &choice = finder.get_alternatives().front();
    141143                Expression *newExpr = choice.expr->clone();
    142                 finishExpr( newExpr, choice.env );
    143                 return newExpr;
     144                finishExpr( newExpr, choice.env, untyped->env );
     145                delete untyped;
     146                untyped = newExpr;
     147        }
     148
     149        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
     150                assert( untyped && type );
     151                untyped = new CastExpr( untyped, type );
     152                findSingleExpression( untyped, indexer );
     153                if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( untyped ) ) {
     154                        if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
     155                                // cast is to the same type as its argument, so it's unnecessary -- remove it
     156                                untyped = castExpr->arg;
     157                                castExpr->arg = nullptr;
     158                                delete castExpr;
     159                        }
     160                }
    144161        }
    145162
     
    157174                }
    158175
    159                 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     176                void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    160177                        TypeEnvironment env;
    161178                        AlternativeFinder finder( indexer, env );
     
    186203                                throw SemanticError( "No interpretations for case control expression", untyped );
    187204                        } // if
    188                         finishExpr( newExpr, *newEnv );
    189                         return newExpr;
     205                        finishExpr( newExpr, *newEnv, untyped->env );
     206                        delete untyped;
     207                        untyped = newExpr;
    190208                }
    191209
     
    212230        void Resolver::handlePtrType( PtrType * type ) {
    213231                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 );
     232                        findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
    218233                }
    219234        }
     
    268283        void Resolver::previsit( ExprStmt *exprStmt ) {
    269284                visit_children = false;
    270                 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    271                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
    272                 delete exprStmt->get_expr();
    273                 exprStmt->set_expr( newExpr );
     285                assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
     286                findVoidExpression( exprStmt->expr, indexer );
    274287        }
    275288
    276289        void Resolver::previsit( AsmExpr *asmExpr ) {
    277290                visit_children = false;
    278                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
    279                 delete asmExpr->get_operand();
    280                 asmExpr->set_operand( newExpr );
     291                findVoidExpression( asmExpr->operand, indexer );
    281292                if ( asmExpr->get_inout() ) {
    282                         newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
    283                         delete asmExpr->get_inout();
    284                         asmExpr->set_inout( newExpr );
     293                        findVoidExpression( asmExpr->inout, indexer );
    285294                } // if
    286295        }
     
    293302
    294303        void Resolver::previsit( IfStmt *ifStmt ) {
    295                 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
    296                 delete ifStmt->get_condition();
    297                 ifStmt->set_condition( newExpr );
     304                findSingleExpression( ifStmt->condition, indexer );
    298305        }
    299306
    300307        void Resolver::previsit( WhileStmt *whileStmt ) {
    301                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
    302                 delete whileStmt->get_condition();
    303                 whileStmt->set_condition( newExpr );
     308                findSingleExpression( whileStmt->condition, indexer );
    304309        }
    305310
    306311        void Resolver::previsit( ForStmt *forStmt ) {
    307                 if ( forStmt->get_condition() ) {
    308                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
    309                         delete forStmt->get_condition();
    310                         forStmt->set_condition( newExpr );
     312                if ( forStmt->condition ) {
     313                        findSingleExpression( forStmt->condition, indexer );
    311314                } // if
    312315
    313                 if ( forStmt->get_increment() ) {
    314                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
    315                         delete forStmt->get_increment();
    316                         forStmt->set_increment( newExpr );
     316                if ( forStmt->increment ) {
     317                        findVoidExpression( forStmt->increment, indexer );
    317318                } // if
    318319        }
     
    320321        void Resolver::previsit( SwitchStmt *switchStmt ) {
    321322                GuardValue( currentObject );
    322                 Expression *newExpr;
    323                 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
    324                 delete switchStmt->get_condition();
    325                 switchStmt->set_condition( newExpr );
    326 
    327                 currentObject = CurrentObject( newExpr->get_result() );
     323                findIntegralExpression( switchStmt->condition, indexer );
     324
     325                currentObject = CurrentObject( switchStmt->condition->result );
    328326        }
    329327
     
    332330                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    333331                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    334                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    335                         Expression * newExpr = findSingleExpression( castExpr, indexer );
    336                         castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    337                         caseStmt->set_condition( castExpr->get_arg() );
    338                         castExpr->set_arg( nullptr );
     332                        // must remove cast from case statement because RangeExpr cannot be cast.
     333                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
     334                        findSingleExpression( newExpr, indexer );
     335                        CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
     336                        caseStmt->condition = castExpr->arg;
     337                        castExpr->arg = nullptr;
    339338                        delete castExpr;
    340339                }
     
    345344                // must resolve the argument for a computed goto
    346345                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
    347                         if ( Expression * arg = branchStmt->get_computedTarget() ) {
    348                                 VoidType v = Type::Qualifiers();                // cast to void * for the alternative finder
    349                                 PointerType pt( Type::Qualifiers(), v.clone() );
    350                                 CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    351                                 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
    352                                 branchStmt->set_target( newExpr );
     346                        if ( branchStmt->computedTarget ) {
     347                                // computed goto argument is void *
     348                                findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer );
    353349                        } // if
    354350                } // if
     
    357353        void Resolver::previsit( ReturnStmt *returnStmt ) {
    358354                visit_children = false;
    359                 if ( returnStmt->get_expr() ) {
    360                         CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    361                         Expression *newExpr = findSingleExpression( castExpr, indexer );
    362                         delete castExpr;
    363                         returnStmt->set_expr( newExpr );
     355                if ( returnStmt->expr ) {
     356                        findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer );
    364357                } // if
    365358        }
     
    372365                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    373366                        assert( exception_decl );
    374                         Expression * wrapped = new CastExpr(
    375                                 throwStmt->get_expr(),
    376                                 new PointerType(
    377                                         noQualifiers,
    378                                         new StructInstType(
    379                                                 noQualifiers,
    380                                                 exception_decl
    381                                                 )
    382                                         )
    383                                 );
    384                         Expression * newExpr = findSingleExpression( wrapped, indexer );
    385                         throwStmt->set_expr( newExpr );
     367                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     368                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    386369                }
    387370        }
    388371
    389372        void Resolver::previsit( CatchStmt *catchStmt ) {
    390                 if ( catchStmt->get_cond() ) {
    391                         Expression * wrapped = new CastExpr(
    392                                 catchStmt->get_cond(),
    393                                 new BasicType( noQualifiers, BasicType::Bool )
    394                                 );
    395                         catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
    396                 }
    397         }
    398 
    399         inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {
    400                 if( !expr ) return;
    401                 Expression * newExpr = findSingleExpression( expr, indexer );
    402                 delete expr;
    403                 expr = newExpr;
    404         }
    405 
    406         inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {
    407                 if( !expr ) return;
    408                 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );
    409                 delete expr;
    410                 expr = newExpr;
     373                if ( catchStmt->cond ) {
     374                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     375                }
    411376        }
    412377
     
    578543                        // Resolve the conditions as if it were an IfStmt
    579544                        // Resolve the statments normally
    580                         resolveAsIf( clause.condition, this->indexer );
     545                        findSingleExpression( clause.condition, this->indexer );
    581546                        clause.statement->accept( *visitor );
    582547                }
     
    587552                        // Resolve the conditions as if it were an IfStmt
    588553                        // Resolve the statments normally
    589                         resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
    590                         resolveAsIf  ( stmt->timeout.condition, this->indexer );
     554                        findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
     555                        findSingleExpression( stmt->timeout.condition, this->indexer );
    591556                        stmt->timeout.statement->accept( *visitor );
    592557                }
     
    595560                        // Resolve the conditions as if it were an IfStmt
    596561                        // Resolve the statments normally
    597                         resolveAsIf( stmt->orelse.condition, this->indexer );
     562                        findSingleExpression( stmt->orelse.condition, this->indexer );
    598563                        stmt->orelse.statement->accept( *visitor );
    599564                }
     
    612577                visit_children = false;
    613578                // resolve initialization using the possibilities as determined by the currentObject cursor
    614                 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    615                 Expression * newExpr = findSingleExpression( untyped, indexer );
     579                Expression * newExpr = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
     580                findSingleExpression( newExpr, indexer );
    616581                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    617582
     
    620585
    621586                // discard InitExpr wrapper and retain relevant pieces
    622                 newExpr = initExpr->get_expr();
    623                 newExpr->set_env( initExpr->get_env() );
    624                 initExpr->set_expr( nullptr );
    625                 initExpr->set_env( nullptr );
     587                newExpr = initExpr->expr;
     588                initExpr->expr = nullptr;
     589                std::swap( initExpr->env, newExpr->env );
    626590                delete initExpr;
    627591
Note: See TracChangeset for help on using the changeset viewer.