Changes in / [f184ca3:61accc5]


Ignore:
Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rf184ca3 r61accc5  
    836836                assertf( ! genC, "Deleted expressions should not reach code generation." );
    837837                expr->expr->accept( *visitor );
     838        }
     839
     840        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
     841                assertf( ! genC, "Default argument expressions should not reach code generation." );
     842                arg->expr->accept( *visitor );
    838843        }
    839844
  • src/CodeGen/CodeGenerator.h

    rf184ca3 r61accc5  
    9494                void postvisit( ConstructorExpr * );
    9595                void postvisit( DeletedExpr * );
     96                void postvisit( DefaultArgExpr * );
    9697                void postvisit( GenericExpr * );
    9798
  • src/Common/PassVisitor.h

    rf184ca3 r61accc5  
    125125        virtual void visit( InitExpr *  initExpr ) override final;
    126126        virtual void visit( DeletedExpr *  delExpr ) override final;
     127        virtual void visit( DefaultArgExpr * argExpr ) override final;
    127128        virtual void visit( GenericExpr * genExpr ) override final;
    128129
     
    224225        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    225226        virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
     227        virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
    226228        virtual Expression * mutate( GenericExpr * genExpr ) override final;
    227229
     
    258260
    259261private:
     262        bool inFunction = false;
     263
    260264        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    261265        template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
  • src/Common/PassVisitor.impl.h

    rf184ca3 r61accc5  
    404404                        indexerAddId( &func );
    405405                        maybeAccept_impl( node->type, *this );
     406                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     407                        // a new scope if inFunction is true
     408                        ValueGuard< bool > oldInFunction( inFunction );
     409                        inFunction = true;
    406410                        maybeAccept_impl( node->statements, *this );
    407411                        maybeAccept_impl( node->attributes, *this );
     
    434438                        indexerAddId( &func );
    435439                        maybeMutate_impl( node->type, *this );
     440                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     441                        // a new scope if inFunction is true
     442                        ValueGuard< bool > oldInFunction( inFunction );
     443                        inFunction = true;
    436444                        maybeMutate_impl( node->statements, *this );
    437445                        maybeMutate_impl( node->attributes, *this );
     
    712720        VISIT_START( node );
    713721        {
    714                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     722                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     723                ValueGuard< bool > oldInFunction( inFunction );
     724                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    715725                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     726                inFunction = false;
    716727                visitStatementList( node->kids );
    717728        }
     
    723734        MUTATE_START( node );
    724735        {
    725                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     736                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     737                ValueGuard< bool > oldInFunction( inFunction );
     738                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    726739                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     740                inFunction = false;
    727741                mutateStatementList( node->kids );
    728742        }
     
    20842098
    20852099//--------------------------------------------------------------------------
     2100// DefaultArgExpr
     2101template< typename pass_type >
     2102void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
     2103        VISIT_START( node );
     2104
     2105        indexerScopedAccept( node->result, *this );
     2106        maybeAccept_impl( node->expr, *this );
     2107
     2108        VISIT_END( node );
     2109}
     2110
     2111template< typename pass_type >
     2112Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
     2113        MUTATE_START( node );
     2114
     2115        indexerScopedMutate( node->env, *this );
     2116        indexerScopedMutate( node->result, *this );
     2117        maybeMutate_impl( node->expr, *this );
     2118
     2119        MUTATE_END( Expression, node );
     2120}
     2121
     2122//--------------------------------------------------------------------------
    20862123// GenericExpr
    20872124template< typename pass_type >
  • src/ResolvExpr/AlternativeFinder.cc

    rf184ca3 r61accc5  
    176176                                                selected[ mangleName ] = current;
    177177                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    178                                                 PRINT(
    179                                                         std::cerr << "marking ambiguous" << std::endl;
    180                                                 )
    181                                                 mapPlace->second.isAmbiguous = true;
     178                                                // if one of the candidates contains a deleted identifier, can pick the other, since
     179                                                // deleted expressions should not be ambiguous if there is another option that is at least as good
     180                                                if ( findDeletedExpr( candidate->expr ) ) {
     181                                                        // do nothing
     182                                                        PRINT( std::cerr << "candidate is deleted" << std::endl; )
     183                                                } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
     184                                                        PRINT( std::cerr << "current is deleted" << std::endl; )
     185                                                        selected[ mangleName ] = current;
     186                                                } else {
     187                                                        PRINT(
     188                                                                std::cerr << "marking ambiguous" << std::endl;
     189                                                        )
     190                                                        mapPlace->second.isAmbiguous = true;
     191                                                }
    182192                                        } else {
    183193                                                PRINT(
     
    335345                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    336346                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    337                         // xxx - this should be improved by memoizing the value of constant exprs
    338                         // during parsing and reusing that information here.
    339                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    340                         int val = 0;
     347                        auto val = constantExpr->intValue();
    341348                        std::string tmp;
    342                         if ( ss >> val && ! (ss >> tmp) ) {
    343                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    344                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    345                                 } // if
     349                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
     350                                alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    346351                        } // if
    347                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    348                         // xxx - temporary hack until 0/1 are int constants
    349                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    350                                 std::stringstream ss( nameExpr->get_name() );
    351                                 int val;
    352                                 ss >> val;
    353                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    354                         }
    355352                } // if
    356353        }
     
    439436                                        return Cost::infinity;
    440437                                }
     438                        }
     439                        if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
     440                                // default arguments should be free - don't include conversion cost.
     441                                // Unwrap them here because they are not relevant to the rest of the system.
     442                                *actualExpr = def->expr;
     443                                ++formal;
     444                                continue;
    441445                        }
    442446                        Type * formalType = (*formal)->get_type();
     
    611615        ConstantExpr* getDefaultValue( Initializer* init ) {
    612616                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    613                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
    614                                 return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     617                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
     618                                return dynamic_cast<ConstantExpr*>( ce->arg );
     619                        } else {
     620                                return dynamic_cast<ConstantExpr*>( si->value );
    615621                        }
    616622                }
     
    873879                                                                indexer ) ) {
    874880                                                        results.emplace_back(
    875                                                                 i, cnstExpr, move(env), move(need), move(have),
     881                                                                i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
    876882                                                                move(openVars), nextArg, nTuples );
    877883                                                }
     
    10651071                funcFinder.findWithAdjustment( untypedExpr->function );
    10661072                // if there are no function alternatives, then proceeding is a waste of time.
     1073                // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    10671074                if ( funcFinder.alternatives.empty() ) return;
    10681075
  • src/ResolvExpr/Resolver.h

    rf184ca3 r61accc5  
    3636        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3737        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
     38        /// Searches expr and returns the first DeletedExpr found, otherwise nullptr
     39        DeletedExpr * findDeletedExpr( Expression * expr );
    3840} // namespace ResolvExpr
    3941
  • src/SynTree/Expression.cc

    rf184ca3 r61accc5  
    746746        os << std::endl << indent+1 << "... deleted by: ";
    747747        deleteStmt->print( os, indent+1 );
     748}
     749
     750
     751DefaultArgExpr::DefaultArgExpr( Expression * expr ) : expr( expr ) {
     752        assert( expr->result );
     753        result = expr->result->clone();
     754}
     755DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {}
     756DefaultArgExpr::~DefaultArgExpr() {
     757        delete expr;
     758}
     759
     760void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const {
     761        os << "Default Argument Expression" << std::endl << indent+1;
     762        expr->print( os, indent+1 );
    748763}
    749764
  • src/SynTree/Expression.h

    rf184ca3 r61accc5  
    865865};
    866866
     867/// expression wrapping the use of a default argument - should never make it past the resolver.
     868class DefaultArgExpr : public Expression {
     869public:
     870        Expression * expr;
     871
     872        DefaultArgExpr( Expression * expr );
     873        DefaultArgExpr( const DefaultArgExpr & other );
     874        ~DefaultArgExpr();
     875
     876        virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
     877        virtual void accept( Visitor & v ) { v.visit( this ); }
     878        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     879        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     880};
     881
    867882/// C11 _Generic expression
    868883class GenericExpr : public Expression {
  • src/SynTree/Mutator.h

    rf184ca3 r61accc5  
    9393        virtual Expression * mutate( InitExpr  * initExpr ) = 0;
    9494        virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
     95        virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0;
    9596        virtual Expression * mutate( GenericExpr * genExpr ) = 0;
    9697
  • src/SynTree/SynTree.h

    rf184ca3 r61accc5  
    101101class InitExpr;
    102102class DeletedExpr;
     103class DefaultArgExpr;
    103104class GenericExpr;
    104105
  • src/SynTree/Visitor.h

    rf184ca3 r61accc5  
    9595        virtual void visit( InitExpr *  initExpr ) = 0;
    9696        virtual void visit( DeletedExpr * delExpr ) = 0;
     97        virtual void visit( DefaultArgExpr * argExpr ) = 0;
    9798        virtual void visit( GenericExpr * genExpr ) = 0;
    9899
Note: See TracChangeset for help on using the changeset viewer.