Changeset cdb990a


Ignore:
Timestamp:
May 18, 2018, 6:45:18 PM (3 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
ccdab45
Parents:
95642c9
git-author:
Rob Schluntz <rschlunt@…> (05/18/18 18:04:11)
git-committer:
Rob Schluntz <rschlunt@…> (05/18/18 18:45:18)
Message:

Strip redundant casts after every resolution

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r95642c9 rcdb990a  
    127127
    128128        namespace {
    129                 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     129                struct StripCasts {
     130                        Expression * postmutate( CastExpr * castExpr ) {
     131                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     132                                        // generated cast is to the same type as its argument, so it's unnecessary -- remove it
     133                                        Expression * expr = castExpr->arg;
     134                                        castExpr->arg = nullptr;
     135                                        std::swap( expr->env, castExpr->env );
     136                                        return expr;
     137                                }
     138                                return castExpr;
     139                        }
     140
     141                        static void strip( Expression *& expr ) {
     142                                PassVisitor<StripCasts> stripper;
     143                                expr = expr->acceptMutator( stripper );
     144                        }
     145                };
     146
     147                void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
    130148                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    131                         env.makeSubstitution( *expr->get_env() );
     149                        env.makeSubstitution( *expr->env );
     150                        StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
    132151                }
    133152
     
    414433
    415434        void Resolver::previsit( CaseStmt *caseStmt ) {
    416                 if ( caseStmt->get_condition() ) {
     435                if ( caseStmt->condition ) {
    417436                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    418437                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     
    420439                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
    421440                        findSingleExpression( newExpr, indexer );
    422                         CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    423                         caseStmt->condition = castExpr->arg;
    424                         castExpr->arg = nullptr;
    425                         delete castExpr;
     441                        // case condition cannot have a cast in C, so it must be removed, regardless of whether it performs a conversion.
     442                        // Ideally we would perform the conversion internally here.
     443                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( newExpr ) ) {
     444                                newExpr = castExpr->arg;
     445                                castExpr->arg = nullptr;
     446                                std::swap( newExpr->env, castExpr->env );
     447                                delete castExpr;
     448                        }
     449                        caseStmt->condition = newExpr;
    426450                }
    427451        }
     
    718742                initExpr->expr = nullptr;
    719743                std::swap( initExpr->env, newExpr->env );
    720                 std::swap( initExpr->inferParams, newExpr->inferParams ) ;
     744                // InitExpr may have inferParams in the case where the expression specializes a function pointer,
     745                // and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
     746                newExpr->spliceInferParams( initExpr );
    721747                delete initExpr;
    722748
  • src/SynTree/Expression.cc

    r95642c9 rcdb990a  
    5050}
    5151
     52void Expression::spliceInferParams( Expression * other ) {
     53        if ( ! other ) return;
     54        for ( auto p : other->inferParams ) {
     55                inferParams[p.first] = std::move( p.second );
     56        }
     57}
     58
    5259Expression::~Expression() {
    5360        delete env;
  • src/SynTree/Expression.h

    r95642c9 rcdb990a  
    7676        InferredParams & get_inferParams() { return inferParams; }
    7777
     78        // move other's inferParams to this
     79        void spliceInferParams( Expression * other );
     80
    7881        virtual Expression * clone() const override = 0;
    7982        virtual void accept( Visitor & v ) override = 0;
Note: See TracChangeset for help on using the changeset viewer.