Changes in / [281806b:e2e7330]


Ignore:
Location:
src
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.h

    r281806b re2e7330  
    291291        bool_ref * get_visit_children_ptr() { return visit_children_impl(pass, 0); }
    292292
    293         void indexerScopeEnter  ()                             { indexer_impl_enterScope  ( pass, 0       ); }
    294         void indexerScopeLeave  ()                             { indexer_impl_leaveScope  ( pass, 0       ); }
    295         void indexerAddId       ( DeclarationWithType * node ) { indexer_impl_addId       ( pass, 0, node ); }
    296         void indexerAddType     ( NamedTypeDecl       * node ) { indexer_impl_addType     ( pass, 0, node ); }
    297         void indexerAddStruct   ( const std::string   & id   ) { indexer_impl_addStruct   ( pass, 0, id   ); }
    298         void indexerAddStruct   ( StructDecl          * node ) { indexer_impl_addStruct   ( pass, 0, node ); }
    299         void indexerAddStructFwd( StructDecl          * node ) { indexer_impl_addStructFwd( pass, 0, node ); }
    300         void indexerAddEnum     ( EnumDecl            * node ) { indexer_impl_addEnum     ( pass, 0, node ); }
    301         void indexerAddUnion    ( const std::string   & id   ) { indexer_impl_addUnion    ( pass, 0, id   ); }
    302         void indexerAddUnion    ( UnionDecl           * node ) { indexer_impl_addUnion    ( pass, 0, node ); }
    303         void indexerAddUnionFwd ( UnionDecl           * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    304         void indexerAddTrait    ( TraitDecl           * node ) { indexer_impl_addTrait    ( pass, 0, node ); }
    305         void indexerAddWith     ( WithStmt            * node ) { indexer_impl_addWith    ( pass, 0, node ); }
     293        void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
     294        void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
     295        void indexerAddId       ( DeclarationWithType       * node ) { indexer_impl_addId       ( pass, 0, node ); }
     296        void indexerAddType     ( NamedTypeDecl             * node ) { indexer_impl_addType     ( pass, 0, node ); }
     297        void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
     298        void indexerAddStruct   ( StructDecl                * node ) { indexer_impl_addStruct   ( pass, 0, node ); }
     299        void indexerAddStructFwd( StructDecl                * node ) { indexer_impl_addStructFwd( pass, 0, node ); }
     300        void indexerAddEnum     ( EnumDecl                  * node ) { indexer_impl_addEnum     ( pass, 0, node ); }
     301        void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
     302        void indexerAddUnion    ( UnionDecl                 * node ) { indexer_impl_addUnion    ( pass, 0, node ); }
     303        void indexerAddUnionFwd ( UnionDecl                 * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
     304        void indexerAddTrait    ( TraitDecl                 * node ) { indexer_impl_addTrait    ( pass, 0, node ); }
     305        void indexerAddWith     ( std::list< Expression * > & exprs ) { indexer_impl_addWith     ( pass, 0, exprs ); }
    306306
    307307
  • src/Common/PassVisitor.impl.h

    r281806b re2e7330  
    365365        maybeAccept_impl   ( node->attributes   , *this );
    366366
    367         if ( node->name != "" ) {
    368                 indexerAddId( node );
    369         }
     367        indexerAddId( node );
    370368
    371369        VISIT_END( node );
     
    381379        maybeMutate_impl   ( node->attributes   , *this );
    382380
    383         if ( node->name != "" ) {
    384                 indexerAddId( node );
    385         }
     381        indexerAddId( node );
    386382
    387383        MUTATE_END( DeclarationWithType, node );
     
    394390        VISIT_START( node );
    395391
    396         if ( node->name != "" ) {
    397                 indexerAddId( node );
    398         }
    399 
    400         {
    401                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    402                 // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    403                 static ObjectDecl func(
    404                         "__func__", noStorageClasses, LinkageSpec::C, nullptr,
    405                         new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
    406                         nullptr
    407                 );
    408                 indexerAddId( &func );
    409                 maybeAccept_impl( node->type, *this );
    410                 maybeAccept_impl( node->statements, *this );
    411                 maybeAccept_impl( node->attributes, *this );
     392        indexerAddId( node );
     393
     394        maybeAccept_impl( node->withExprs, *this );
     395        {
     396                // with clause introduces a level of scope (for the with expression members).
     397                // with clause exprs are added to the indexer before parameters so that parameters
     398                // shadow with exprs and not the other way around.
     399                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     400                indexerAddWith( node->withExprs );
     401                {
     402                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     403                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
     404                        static ObjectDecl func(
     405                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
     406                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
     407                                nullptr
     408                        );
     409                        indexerAddId( &func );
     410                        maybeAccept_impl( node->type, *this );
     411                        maybeAccept_impl( node->statements, *this );
     412                        maybeAccept_impl( node->attributes, *this );
     413                }
    412414        }
    413415
     
    419421        MUTATE_START( node );
    420422
    421         if ( node->name != "" ) {
    422                 indexerAddId( node );
    423         }
    424 
    425         {
    426                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    427                 // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    428                 static ObjectDecl func(
    429                         "__func__", noStorageClasses, LinkageSpec::C, nullptr,
    430                         new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
    431                         nullptr
    432                 );
    433                 indexerAddId( &func );
    434                 maybeMutate_impl( node->type, *this );
    435                 maybeMutate_impl( node->statements, *this );
    436                 maybeMutate_impl( node->attributes, *this );
     423        indexerAddId( node );
     424
     425        {
     426                // with clause introduces a level of scope (for the with expression members).
     427                // with clause exprs are added to the indexer before parameters so that parameters
     428                // shadow with exprs and not the other way around.
     429                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     430                indexerAddWith( node->withExprs );
     431                {
     432                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     433                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
     434                        static ObjectDecl func(
     435                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
     436                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
     437                                nullptr
     438                        );
     439                        indexerAddId( &func );
     440                        maybeMutate_impl( node->type, *this );
     441                        maybeMutate_impl( node->statements, *this );
     442                        maybeMutate_impl( node->attributes, *this );
     443                }
    437444        }
    438445
     
    730737template< typename pass_type >
    731738void PassVisitor< pass_type >::visit( AsmStmt * node ) {
    732         VISIT_BODY( node );
     739        VISIT_START( node )
     740
     741        maybeAccept_impl( node->instruction, *this );
     742        maybeAccept_impl( node->output, *this );
     743        maybeAccept_impl( node->input, *this );
     744        maybeAccept_impl( node->clobber, *this );
     745
     746        VISIT_END( node );
    733747}
    734748
    735749template< typename pass_type >
    736750Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    737         MUTATE_BODY( Statement, node );
     751        MUTATE_START( node );
     752
     753        maybeMutate_impl( node->instruction, *this );
     754        maybeMutate_impl( node->output, *this );
     755        maybeMutate_impl( node->input, *this );
     756        maybeMutate_impl( node->clobber, *this );
     757
     758        MUTATE_END( Statement, node );
    738759}
    739760
     
    9961017                // catch statements introduce a level of scope (for the caught exception)
    9971018                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    998                 indexerAddWith( node );
     1019                indexerAddWith( node->exprs );
    9991020                maybeAccept_impl( node->stmt, *this );
    10001021        }
     
    10091030                // catch statements introduce a level of scope (for the caught exception)
    10101031                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1011                 indexerAddWith( node );
     1032                indexerAddWith( node->exprs );
    10121033                maybeMutate_impl( node->stmt, *this );
    10131034        }
  • src/Common/PassVisitor.proto.h

    r281806b re2e7330  
    202202static inline void indexer_impl_##func ( pass_type &, long, type ) { }                                                          \
    203203
    204 INDEXER_FUNC( addId     , DeclarationWithType * );
    205 INDEXER_FUNC( addType   , NamedTypeDecl *       );
    206 INDEXER_FUNC( addStruct , StructDecl *          );
    207 INDEXER_FUNC( addEnum   , EnumDecl *            );
    208 INDEXER_FUNC( addUnion  , UnionDecl *           );
    209 INDEXER_FUNC( addTrait  , TraitDecl *           );
    210 INDEXER_FUNC( addWith   , WithStmt *            );
     204INDEXER_FUNC( addId     , DeclarationWithType *       );
     205INDEXER_FUNC( addType   , NamedTypeDecl *             );
     206INDEXER_FUNC( addStruct , StructDecl *                );
     207INDEXER_FUNC( addEnum   , EnumDecl *                  );
     208INDEXER_FUNC( addUnion  , UnionDecl *                 );
     209INDEXER_FUNC( addTrait  , TraitDecl *                 );
     210INDEXER_FUNC( addWith   , std::list< Expression * > & );
    211211
    212212
  • src/Parser/DeclarationNode.cc

    r281806b re2e7330  
    723723}
    724724
    725 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) {
     725DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) {
    726726        assert( type );
    727727        assert( type->kind == TypeData::Function );
    728728        assert( ! type->function.body );
    729         if ( with ) {
    730                 // convert
    731                 //  void f(S s) with (s) { x = 0; }
    732                 // to
    733                 //  void f(S s) { with(s) { x = 0; } }
    734                 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() );
    735                 withStmt->stmt = body->build();
    736                 delete body;
    737                 delete with;
    738                 body = new StatementNode( new CompoundStmt( { withStmt } ) );
    739         }
    740729        type->function.body = body;
     730        type->function.withExprs = withExprs;
    741731        return this;
    742732}
  • src/Parser/ParseNode.h

    r281806b re2e7330  
    262262        DeclarationNode * addBitfield( ExpressionNode * size );
    263263        DeclarationNode * addVarArgs();
    264         DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr );
     264        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
    265265        DeclarationNode * addOldDeclList( DeclarationNode * list );
    266266        DeclarationNode * setBase( TypeData * newType );
  • src/Parser/TypeData.cc

    r281806b re2e7330  
    5555                function.body = nullptr;
    5656                function.newStyle = false;
     57                function.withExprs = nullptr;
    5758                break;
    5859                // Enum is an Aggregate, so both structures are initialized together.
     
    122123                delete function.oldDeclList;
    123124                delete function.body;
     125                delete function.withExprs;
    124126                // delete function;
    125127                break;
     
    194196                newtype->function.body = maybeClone( function.body );
    195197                newtype->function.newStyle = function.newStyle;
     198                newtype->function.withExprs = maybeClone( function.withExprs );
    196199                break;
    197200          case Aggregate:
     
    861864                CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
    862865                decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
     866                buildList( td->function.withExprs, decl->withExprs );
    863867                return decl->set_asmName( asmName );
    864868        } else if ( td->kind == TypeData::Aggregate ) {
  • src/Parser/TypeData.h

    r281806b re2e7330  
    6565                StatementNode * body;
    6666                bool newStyle;
     67                ExpressionNode * withExprs;             // expressions from function's with_clause
    6768        };
    6869
  • src/Parser/parser.yy

    r281806b re2e7330  
    259259%type<sn> iteration_statement                   jump_statement
    260260%type<sn> expression_statement                  asm_statement
    261 %type<sn> with_statement                                with_clause_opt
     261%type<sn> with_statement
     262%type<en> with_clause_opt
    262263%type<sn> exception_statement                   handler_clause                          finally_clause
    263264%type<catch_kind> handler_key
     
    24172418                { $$ = nullptr; }
    24182419        | WITH '(' tuple_expression_list ')'
    2419                 { $$ = new StatementNode( build_with( $3, nullptr ) ); }
     2420                { $$ = $3; }
    24202421        ;
    24212422
  • src/ResolvExpr/Resolver.cc

    r281806b re2e7330  
    8282                void previsit( ConstructorInit *ctorInit );
    8383          private:
    84         typedef std::list< Initializer * >::iterator InitIterator;
     84                typedef std::list< Initializer * >::iterator InitIterator;
    8585
    8686                template< typename PtrType >
    8787                void handlePtrType( PtrType * type );
    8888
    89           void resolveAggrInit( ReferenceToType *, InitIterator &, InitIterator & );
    90           void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator &, TypeSubstitution sub );
    91           void fallbackInit( ConstructorInit * ctorInit );
     89                void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
     90                void fallbackInit( ConstructorInit * ctorInit );
    9291
    9392                Type * functionReturn = nullptr;
     
    269268                std::cerr << std::endl;
    270269#endif
    271                 Type *new_type = resolveTypeof( functionDecl->get_type(), indexer );
     270                Type *new_type = resolveTypeof( functionDecl->type, indexer );
    272271                functionDecl->set_type( new_type );
    273272                GuardValue( functionReturn );
    274                 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
     273                functionReturn = ResolvExpr::extractResultType( functionDecl->type );
     274
     275                {
     276                        // resolve with-exprs with parameters in scope and add any newly generated declarations to the
     277                        // front of the function body.
     278                        auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this](){ indexer.leaveScope(); } );
     279                        indexer.addFunctionType( functionDecl->type );
     280                        std::list< Statement * > newStmts;
     281                        resolveWithExprs( functionDecl->withExprs, newStmts );
     282                        functionDecl->statements->kids.splice( functionDecl->statements->kids.begin(), newStmts );
     283                }
    275284        }
    276285
     
    279288                // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
    280289                // see how it's useful.
    281                 for ( Declaration * d : functionDecl->get_functionType()->get_parameters() ) {
     290                for ( Declaration * d : functionDecl->type->parameters ) {
    282291                        if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) {
    283                                 if ( SingleInit * init = dynamic_cast< SingleInit * >( obj->get_init() ) ) {
    284                                         delete init->get_value()->get_env();
    285                                         init->get_value()->set_env( nullptr );
     292                                if ( SingleInit * init = dynamic_cast< SingleInit * >( obj->init ) ) {
     293                                        delete init->value->env;
     294                                        init->value->env = nullptr;
    286295                                }
    287296                        }
     
    584593        }
    585594
    586 
    587         void Resolver::previsit( WithStmt * withStmt ) {
    588                 for ( Expression *& expr : withStmt->exprs )  {
     595        void Resolver::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) {
     596                for ( Expression *& expr : withExprs )  {
    589597                        // only struct- and union-typed expressions are viable candidates
    590598                        findKindExpression( expr, indexer, "with statement", isStructOrUnion );
     
    595603                                ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
    596604                                expr = new VariableExpr( tmp );
    597                                 stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
     605                                newStmts.push_back( new DeclStmt( tmp ) );
    598606                                if ( InitTweak::isConstructable( tmp->type ) ) {
    599607                                        // generate ctor/dtor and resolve them
     
    603611                        }
    604612                }
     613        }
     614
     615        void Resolver::previsit( WithStmt * withStmt ) {
     616                resolveWithExprs( withStmt->exprs, stmtsToAddBefore );
    605617        }
    606618
     
    716728                PassVisitor<Resolver> resolver( indexer );
    717729                stmtExpr->accept( resolver );
     730                stmtExpr->computeResult();
    718731        }
    719732
  • src/SymTab/Indexer.cc

    r281806b re2e7330  
    409409
    410410        void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) {
     411                if ( decl->name == "" ) return;
    411412                debugPrint( "Adding Id " << decl->name << std::endl );
    412413                makeWritable();
     
    588589        }
    589590
    590         void Indexer::addWith( WithStmt * stmt ) {
    591                 for ( Expression * expr : stmt->exprs ) {
     591        void Indexer::addWith( std::list< Expression * > & withExprs ) {
     592                for ( Expression * expr : withExprs ) {
    592593                        if ( expr->result ) {
    593594                                AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
  • src/SymTab/Indexer.h

    r281806b re2e7330  
    8484
    8585                /// adds all of the IDs from WithStmt exprs
    86                 void addWith( WithStmt * );
     86                void addWith( std::list< Expression * > & withExprs );
    8787
    8888                /// adds all of the members of the Aggregate (addWith helper)
  • src/SynTree/Declaration.h

    r281806b re2e7330  
    151151        FunctionType *type;
    152152        CompoundStmt *statements;
     153        std::list< Expression * > withExprs;
    153154
    154155        FunctionDecl( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, FunctionType *type, CompoundStmt *statements,
  • src/SynTree/Expression.cc

    r281806b re2e7330  
    597597
    598598StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
     599        computeResult();
     600}
     601StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
     602        cloneAll( other.returnDecls, returnDecls );
     603        cloneAll( other.dtors, dtors );
     604}
     605StmtExpr::~StmtExpr() {
     606        delete statements;
     607        deleteAll( dtors );
     608        deleteAll( returnDecls );
     609}
     610void StmtExpr::computeResult() {
    599611        assert( statements );
    600         std::list< Statement * > & body = statements->get_kids();
     612        std::list< Statement * > & body = statements->kids;
     613        delete result;
     614        result = nullptr;
    601615        if ( ! body.empty() ) {
    602616                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
     
    608622                result = new VoidType( Type::Qualifiers() );
    609623        }
    610 }
    611 StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
    612         cloneAll( other.returnDecls, returnDecls );
    613         cloneAll( other.dtors, dtors );
    614 }
    615 StmtExpr::~StmtExpr() {
    616         delete statements;
    617         deleteAll( dtors );
    618         deleteAll( returnDecls );
    619624}
    620625void StmtExpr::print( std::ostream &os, Indenter indent ) const {
  • src/SynTree/Expression.h

    r281806b re2e7330  
    728728        StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
    729729
     730        // call to set the result type of this StmtExpr based on its body
     731        void computeResult();
     732
    730733        std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
    731734        std::list< Expression * > & get_dtors() { return dtors; }
  • src/SynTree/FunctionDecl.cc

    r281806b re2e7330  
    5151                VarExprReplacer::replace( this, declMap );
    5252        }
     53        cloneAll( other.withExprs, withExprs );
    5354}
    5455
     
    5657        delete type;
    5758        delete statements;
     59        deleteAll( withExprs );
    5860}
    5961
Note: See TracChangeset for help on using the changeset viewer.