Changes in / [65197c2:12d2dc8]


Ignore:
Location:
src
Files:
2 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r65197c2 r12d2dc8  
    10121012        }
    10131013
    1014         void CodeGenerator::postvisit( WithStmt * with ) {
    1015                 if ( ! genC ) {
    1016                         output << "with ( ";
    1017                         genCommaList( with->exprs.begin(), with->exprs.end() );
    1018                         output << " ) ";
    1019                 }
    1020                 with->stmt->accept( *visitor );
    1021         }
    10221014
    10231015        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
  • src/CodeGen/CodeGenerator.h

    r65197c2 r12d2dc8  
    102102                void postvisit( CatchStmt * );
    103103                void postvisit( WaitForStmt * );
    104                 void postvisit( WithStmt * );
    105104                void postvisit( WhileStmt * );
    106105                void postvisit( ForStmt * );
  • src/Common/PassVisitor.h

    r65197c2 r12d2dc8  
    8181        virtual void visit( FinallyStmt * finallyStmt ) override final;
    8282        virtual void visit( WaitForStmt * waitforStmt ) override final;
    83         virtual void visit( WithStmt * withStmt ) override final;
    8483        virtual void visit( NullStmt * nullStmt ) override final;
    8584        virtual void visit( DeclStmt * declStmt ) override final;
     
    173172        virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
    174173        virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
    175         virtual Statement * mutate( WithStmt * withStmt ) override final;
    176174        virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
    177175        virtual Statement * mutate( DeclStmt * declStmt ) override final;
     
    298296        void indexerAddUnionFwd ( UnionDecl           * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    299297        void indexerAddTrait    ( TraitDecl           * node ) { indexer_impl_addTrait    ( pass, 0, node ); }
    300         void indexerAddWith     ( WithStmt            * node ) { indexer_impl_addWith    ( pass, 0, node ); }
    301 
    302298
    303299        template< typename TreeType, typename VisitorType >
  • src/Common/PassVisitor.impl.h

    r65197c2 r12d2dc8  
    985985}
    986986
    987 
    988 
    989 //--------------------------------------------------------------------------
    990 // NullStmt
    991 template< typename pass_type >
    992 void PassVisitor< pass_type >::visit( WithStmt * node ) {
    993         VISIT_START( node );
    994         maybeAccept_impl( node->exprs, *this );
    995         {
    996                 // catch statements introduce a level of scope (for the caught exception)
    997                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    998                 indexerAddWith( node );
    999                 maybeAccept_impl( node->stmt, *this );
    1000         }
    1001         VISIT_END( node );
    1002 }
    1003 
    1004 template< typename pass_type >
    1005 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
    1006         MUTATE_START( node );
    1007         maybeMutate_impl( node->exprs, *this );
    1008         {
    1009                 // catch statements introduce a level of scope (for the caught exception)
    1010                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    1011                 indexerAddWith( node );
    1012                 maybeMutate_impl( node->stmt, *this );
    1013         }
    1014         MUTATE_END( Statement, node );
    1015 }
    1016 
    1017987//--------------------------------------------------------------------------
    1018988// NullStmt
  • src/Common/PassVisitor.proto.h

    r65197c2 r12d2dc8  
    208208INDEXER_FUNC( addUnion  , UnionDecl *           );
    209209INDEXER_FUNC( addTrait  , TraitDecl *           );
    210 INDEXER_FUNC( addWith   , WithStmt *            );
    211210
    212211
  • src/GenPoly/InstantiateGeneric.cc

    r65197c2 r12d2dc8  
    453453                        return false;
    454454                }
     455
     456                AggregateDecl * getAggr( Type * t ) {
     457                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
     458                                return inst->baseStruct;
     459                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
     460                                return inst->baseUnion;
     461                        }
     462                        assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );
     463                }
    455464        }
    456465
     
    460469                if ( isGenericType( memberExpr->aggregate->result ) ) {
    461470                        // find the location of the member
    462                         AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
     471                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
    463472                        std::list< Declaration * > & members = aggr->members;
    464473                        memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
     
    470479                if ( memberIndex != -1 ) {
    471480                        // using the location from the generic type, find the member in the instantiation and rebuild the member expression
    472                         AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
     481                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
    473482                        assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
    474483                        Declaration * member = *std::next( aggr->members.begin(), memberIndex );
  • src/Parser/DeclarationNode.cc

    r65197c2 r12d2dc8  
    717717}
    718718
    719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) {
     719DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body ) {
    720720        assert( type );
    721721        assert( type->kind == TypeData::Function );
    722722        assert( ! type->function.body );
    723         if ( with ) {
    724                 // convert
    725                 //  void f(S s) with (s) { x = 0; }
    726                 // to
    727                 //  void f(S s) { with(s) { x = 0; } }
    728                 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() );
    729                 withStmt->stmt = body->build();
    730                 delete body;
    731                 delete with;
    732                 body = new StatementNode( new CompoundStmt( { withStmt } ) );
    733         }
    734723        type->function.body = body;
    735724        return this;
  • src/Parser/ParseNode.h

    r65197c2 r12d2dc8  
    6969
    7070        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
    71         virtual void printList( std::ostream &os, int indent = 0 ) const {
    72                 print( os, indent );
    73                 if ( next ) next->print( os, indent );
    74         }
     71        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
    7572
    7673        static int indent_by;
     
    123120        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
    124121
    125         virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
    126                 os << expr.get() << std::endl;
    127         }
     122        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
    128123        void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
    129124
     
    262257        DeclarationNode * addBitfield( ExpressionNode * size );
    263258        DeclarationNode * addVarArgs();
    264         DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr );
     259        DeclarationNode * addFunctionBody( StatementNode * body );
    265260        DeclarationNode * addOldDeclList( DeclarationNode * list );
    266261        DeclarationNode * setBase( TypeData * newType );
     
    364359        virtual StatementNode * append_last_case( StatementNode * );
    365360
    366         virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
    367                 os << stmt.get() << std::endl;
    368         }
     361        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
     362        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
    369363  private:
    370364        std::unique_ptr<Statement> stmt;
     
    414408WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
    415409WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    416 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
    417410
    418411//##############################################################################
  • src/Parser/StatementNode.cc

    r65197c2 r12d2dc8  
    282282        node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    283283
    284         node->orelse.statement  = maybeMoveBuild<Statement >( else_stmt );
     284        node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
    285285        node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
    286286
    287287        return node;
    288 }
    289 
    290 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    291         std::list< Expression * > e;
    292         buildMoveList( exprs, e );
    293         Statement * s = maybeMoveBuild<Statement>( stmt );
    294         return new WithStmt( e, s );
    295288}
    296289
  • src/Parser/parser.yy

    r65197c2 r12d2dc8  
    10581058with_statement:
    10591059        WITH '(' tuple_expression_list ')' statement
    1060                 {
    1061                         $$ = new StatementNode( build_with( $3, $5 ) );
    1062                 }
     1060                { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME
    10631061        ;
    10641062
     
    24122410                { $$ = nullptr; }
    24132411        | WITH '(' tuple_expression_list ')'
    2414                 { $$ = new StatementNode( build_with( $3, nullptr ) ); }
     2412                { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME
    24152413        ;
    24162414
     
    24222420                        // Add the function body to the last identifier in the function definition list, i.e., foo3:
    24232421                        //   [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; }
    2424                         $1->get_last()->addFunctionBody( $3, $2 );
     2422                        $1->get_last()->addFunctionBody( $3 );
    24252423                        $$ = $1;
    24262424                }
     
    24302428                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24312429                        typedefTable.leaveScope();
    2432                         $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
     2430                        $$ = $2->addFunctionBody( $4 )->addType( $1 );
    24332431                }
    24342432                // handles default int return type, OBSOLESCENT (see 1)
     
    24372435                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24382436                        typedefTable.leaveScope();
    2439                         $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     2437                        $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
    24402438                }
    24412439                // handles default int return type, OBSOLESCENT (see 1)
     
    24442442                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24452443                        typedefTable.leaveScope();
    2446                         $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     2444                        $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );
    24472445                }
    24482446                // handles default int return type, OBSOLESCENT (see 1)
     
    24512449                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24522450                        typedefTable.leaveScope();
    2453                         $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
     2451                        $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 );
    24542452                }
    24552453
     
    24602458                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24612459                        typedefTable.leaveScope();
    2462                         $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
     2460                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addType( $1 );
    24632461                }
    24642462                // handles default int return type, OBSOLESCENT (see 1)
     
    24672465                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24682466                        typedefTable.leaveScope();
    2469                         $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     2467                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );
    24702468                }
    24712469                // handles default int return type, OBSOLESCENT (see 1)
     
    24742472                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24752473                        typedefTable.leaveScope();
    2476                         $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     2474                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );
    24772475                }
    24782476                // handles default int return type, OBSOLESCENT (see 1)
     
    24812479                        typedefTable.addToEnclosingScope( TypedefTable::ID );
    24822480                        typedefTable.leaveScope();
    2483                         $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
     2481                        $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
    24842482                }
    24852483        ;
  • src/ResolvExpr/AlternativeFinder.cc

    r65197c2 r12d2dc8  
    8383        }
    8484
    85         void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
    86                 Indenter indent = { Indenter::tabsize, indentAmt };
    87                 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    88                         i->print( os, indent );
    89                         os << std::endl;
    90                 }
    91         }
    92 
    9385        namespace {
     86                void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {
     87                        Indenter indent = { Indenter::tabsize, indentAmt };
     88                        for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     89                                i->print( os, indent );
     90                                os << std::endl;
     91                        }
     92                }
     93
    9494                void makeExprList( const AltList &in, std::list< Expression* > &out ) {
    9595                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     
    469469                        std::cerr << std::endl;
    470470                )
    471                 std::list< SymTab::Indexer::IdData > candidates;
     471                std::list< DeclarationWithType* > candidates;
    472472                decls.lookupId( curDecl->get_name(), candidates );
    473473///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    474                 for ( const auto & data : candidates ) {
    475                         DeclarationWithType * candidate = data.id;
     474                for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
    476475                        PRINT(
    477476                                std::cerr << "inferRecursive: candidate is ";
    478                                 candidate->print( std::cerr );
     477                                (*candidate)->print( std::cerr );
    479478                                std::cerr << std::endl;
    480479                        )
     
    483482                        TypeEnvironment newEnv( newAlt.env );
    484483                        OpenVarSet newOpenVars( openVars );
    485                         Type *adjType = candidate->get_type()->clone();
     484                        Type *adjType = (*candidate)->get_type()->clone();
    486485                        adjustExprType( adjType, newEnv, indexer );
    487486                        adjType->accept( global_renamer );
     
    501500                                Alternative newerAlt( newAlt );
    502501                                newerAlt.env = newEnv;
    503                                 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
     502                                assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );
     503                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
    504504
    505505                                // everything with an empty idChain was pulled in by the current assertion.
     
    516516                                // DOESN'T WORK: grandchild nodes conflict with their cousins
    517517                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    518                                 Expression *varExpr = data.combine();
     518                                Expression *varExpr = new VariableExpr( candDecl );
    519519                                delete varExpr->get_result();
    520520                                varExpr->set_result( adjType->clone() );
     
    522522                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    523523                                        curDecl->print( std::cerr );
    524                                         std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
    525                                         candidate->print( std::cerr );
     524                                        std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";
     525                                        (*candidate)->print( std::cerr );
    526526                                        std::cerr << std::endl;
    527527                                )
     
    532532                                }
    533533                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    534                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     534                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    535535                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    536536                        } else {
     
    13171317
    13181318        void AlternativeFinder::visit( NameExpr *nameExpr ) {
    1319                 std::list< SymTab::Indexer::IdData > declList;
     1319                std::list< DeclarationWithType* > declList;
    13201320                indexer.lookupId( nameExpr->get_name(), declList );
    13211321                PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
    1322                 for ( auto & data : declList ) {
    1323                         Expression * newExpr = data.combine();
    1324                         // xxx - add in extra cost for with-statement exprs?
    1325                         alternatives.push_back( Alternative( newExpr, env, Cost::zero ) );
     1322                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
     1323                        VariableExpr newExpr( *i );
     1324                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    13261325                        PRINT(
    13271326                                std::cerr << "decl is ";
    1328                                 data.id->print( std::cerr );
     1327                                (*i)->print( std::cerr );
    13291328                                std::cerr << std::endl;
    13301329                                std::cerr << "newExpr is ";
    1331                                 newExpr->print( std::cerr );
     1330                                newExpr.print( std::cerr );
    13321331                                std::cerr << std::endl;
    13331332                        )
     
    14211420        }
    14221421
    1423         namespace {
    1424                 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
    1425                         // assume no polymorphism
    1426                         // assume no implicit conversions
    1427                         assert( function->get_parameters().size() == 1 );
    1428                         PRINT(
    1429                                 std::cerr << "resolvAttr: funcDecl is ";
    1430                                 data.id->print( std::cerr );
    1431                                 std::cerr << " argType is ";
    1432                                 argType->print( std::cerr );
    1433                                 std::cerr << std::endl;
    1434                         )
    1435                         const SymTab::Indexer & indexer = finder.get_indexer();
    1436                         AltList & alternatives = finder.get_alternatives();
    1437                         if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    1438                                 alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) );
    1439                                 for ( DeclarationWithType * retVal : function->returnVals ) {
    1440                                         alternatives.back().expr->result = retVal->get_type()->clone();
    1441                                 } // for
    1442                         } // if
    1443                 }
     1422        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
     1423                // assume no polymorphism
     1424                // assume no implicit conversions
     1425                assert( function->get_parameters().size() == 1 );
     1426                PRINT(
     1427                        std::cerr << "resolvAttr: funcDecl is ";
     1428                        funcDecl->print( std::cerr );
     1429                        std::cerr << " argType is ";
     1430                        argType->print( std::cerr );
     1431                        std::cerr << std::endl;
     1432                )
     1433                if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     1434                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
     1435                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
     1436                                alternatives.back().expr->set_result( (*i)->get_type()->clone() );
     1437                        } // for
     1438                } // if
    14441439        }
    14451440
     
    14481443                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    14491444                assert( nameExpr );
    1450                 std::list< SymTab::Indexer::IdData > attrList;
     1445                std::list< DeclarationWithType* > attrList;
    14511446                indexer.lookupId( nameExpr->get_name(), attrList );
    14521447                if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    1453                         for ( auto & data : attrList ) {
    1454                                 DeclarationWithType * id = data.id;
     1448                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    14551449                                // check if the type is function
    1456                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
     1450                                if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
    14571451                                        // assume exactly one parameter
    14581452                                        if ( function->get_parameters().size() == 1 ) {
    14591453                                                if ( attrExpr->get_isType() ) {
    1460                                                         resolveAttr( data, function, attrExpr->get_type(), env, *this );
     1454                                                        resolveAttr( *i, function, attrExpr->get_type(), env );
    14611455                                                } else {
    14621456                                                        AlternativeFinder finder( indexer, env );
     
    14641458                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    14651459                                                                if ( choice->expr->get_result()->size() == 1 ) {
    1466                                                                         resolveAttr(data, function, choice->expr->get_result(), choice->env, *this );
     1460                                                                        resolveAttr(*i, function, choice->expr->get_result(), choice->env );
    14671461                                                                } // fi
    14681462                                                        } // for
     
    14721466                        } // for
    14731467                } else {
    1474                         for ( auto & data : attrList ) {
    1475                                 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) );
     1468                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     1469                                VariableExpr newExpr( *i );
     1470                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    14761471                                renameTypes( alternatives.back().expr );
    14771472                        } // for
  • src/ResolvExpr/AlternativeFinder.h

    r65197c2 r12d2dc8  
    142142                template< typename OutputIterator >
    143143                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     144                void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
    144145
    145146                const SymTab::Indexer &indexer;
     
    150151
    151152        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
     153        void referenceToRvalueConversion( Expression *& expr );
    152154
    153155        template< typename InputIterator, typename OutputIterator >
     
    172174
    173175        Cost sumCost( const AltList &in );
    174         void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 );
    175176
    176177        template< typename InputIterator >
     
    180181                }
    181182        }
    182 
    183183} // namespace ResolvExpr
    184184
  • src/ResolvExpr/Resolver.cc

    r65197c2 r12d2dc8  
    2626#include "Common/utility.h"              // for ValueGuard, group_iterate
    2727#include "CurrentObject.h"               // for CurrentObject
    28 #include "InitTweak/GenInit.h"
    2928#include "InitTweak/InitTweak.h"         // for isIntrinsicSingleArgCallStmt
    3029#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    4140#include "SynTree/TypeSubstitution.h"    // for TypeSubstitution
    4241#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    43 #include "Tuples/Tuples.h"
    4442#include "typeops.h"                     // for extractResultType
    4543#include "Unify.h"                       // for unify
     
    4846
    4947namespace ResolvExpr {
    50         struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd {
     48        struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {
    5149                Resolver() {}
    5250                Resolver( const SymTab::Indexer & other ) {
     
    7674                void previsit( CatchStmt *catchStmt );
    7775                void previsit( WaitForStmt * stmt );
    78                 void previsit( WithStmt * withStmt );
    7976
    8077                void previsit( SingleInit *singleInit );
     
    574571        }
    575572
    576         bool isStructOrUnion( Type * t ) {
    577                 t = t->stripReferences();
    578                 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
    579         }
    580 
    581         void Resolver::previsit( WithStmt * withStmt ) {
    582                 for ( Expression *& expr : withStmt->exprs )  {
    583                         TypeEnvironment env;
    584                         AlternativeFinder finder( indexer, env );
    585                         finder.findWithAdjustment( expr );
    586 
    587                         // only struct- and union-typed expressions are viable candidates
    588                         AltList candidates;
    589                         for ( Alternative & alt : finder.get_alternatives() ) {
    590                                 if ( isStructOrUnion( alt.expr->result ) ) {
    591                                         candidates.push_back( std::move( alt ) );
    592                                 }
    593                         }
    594 
    595                         // choose the lowest cost expression among the candidates
    596                         AltList winners;
    597                         findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
    598                         if ( winners.size() == 0 ) {
    599                                 throw SemanticError( "No reasonable alternatives for with statement expression: ", expr );
    600                         } else if ( winners.size() != 1 ) {
    601                                 std::ostringstream stream;
    602                                 stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n";
    603                                 expr->print( stream );
    604                                 stream << "Alternatives are:\n";
    605                                 printAlts( winners, stream, 1 );
    606                                 throw SemanticError( stream.str() );
    607                         }
    608 
    609                         // there is one unambiguous interpretation - move the expression into the with statement
    610                         Alternative & alt = winners.front();
    611                         finishExpr( alt.expr, alt.env, expr->env );
    612                         delete expr;
    613                         expr = alt.expr;
    614                         alt.expr = nullptr;
    615 
    616                         // if with expression might be impure, create a temporary so that it is evaluated once
    617                         if ( Tuples::maybeImpure( expr ) ) {
    618                                 static UniqueName tmpNamer( "_with_tmp_" );
    619                                 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
    620                                 expr = new VariableExpr( tmp );
    621                                 stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
    622                                 if ( InitTweak::isConstructable( tmp->type ) ) {
    623                                         // generate ctor/dtor and resolve them
    624                                         tmp->init = InitTweak::genCtorInit( tmp );
    625                                         tmp->accept( *visitor );
    626                                 }
    627                         }
    628                 }
    629         }
    630 
    631573        template< typename T >
    632574        bool isCharType( T t ) {
  • src/ResolvExpr/typeops.h

    r65197c2 r12d2dc8  
    102102        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    103103
    104         // in AlternativeFinder.cc
    105         void referenceToRvalueConversion( Expression *& expr );
    106 
    107104        // flatten tuple type into list of types
    108105        template< typename OutputIterator >
  • src/SymTab/Indexer.cc

    r65197c2 r12d2dc8  
    4040
    4141namespace SymTab {
    42         std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) {
    43                 return out << "(" << data.id << "," << data.baseExpr << ")";
    44         }
    45 
    46         typedef std::unordered_map< std::string, Indexer::IdData > MangleTable;
     42        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    4743        typedef std::unordered_map< std::string, MangleTable > IdTable;
    4844        typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
     
    10197        }
    10298
    103         void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
     99        void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const {
    104100                // only need to perform this step for constructors, destructors, and assignment functions
    105101                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
     
    108104                struct ValueType {
    109105                        struct DeclBall {
    110                                 IdData decl;
     106                                FunctionDecl * decl;
    111107                                bool isUserDefinedFunc; // properties for this particular decl
    112108                                bool isDefaultCtor;
     
    124120                        // another FunctionDecl for the current type was found - determine
    125121                        // if it has special properties and update data structure accordingly
    126                         ValueType & operator+=( IdData data ) {
    127                                 DeclarationWithType * function = data.id;
     122                        ValueType & operator+=( FunctionDecl * function ) {
    128123                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    129124                                bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    130125                                bool isDtor = InitTweak::isDestructor( function );
    131126                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    132                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
     127                                decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    133128                                existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    134129                                existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
     
    140135                }; // ValueType
    141136
    142                 std::list< IdData > copy;
     137                std::list< DeclarationWithType * > copy;
    143138                copy.splice( copy.end(), out );
    144139
    145140                // organize discovered declarations by type
    146141                std::unordered_map< std::string, ValueType > funcMap;
    147                 for ( auto decl : copy ) {
    148                         if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
     142                for ( DeclarationWithType * decl : copy ) {
     143                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {
    149144                                std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
    150145                                assert( ! params.empty() );
     
    152147                                Type * base = InitTweak::getPointerBase( params.front()->get_type() );
    153148                                assert( base );
    154                                 funcMap[ Mangler::mangle( base ) ] += decl;
     149                                funcMap[ Mangler::mangle( base ) ] += function;
    155150                        } else {
    156151                                out.push_back( decl );
     
    169164                                bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    170165                                bool isUserDefinedFunc = ball.isUserDefinedFunc;
    171                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
     166                                bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    172167                                bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    173168                                bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
     
    224219        }
    225220
    226         void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
     221        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
    227222                std::unordered_set< std::string > foundMangleNames;
    228223
     
    294289                        const MangleTable &mangleTable = decls->second;
    295290                        MangleTable::const_iterator decl = mangleTable.find( mangleName );
    296                         if ( decl != mangleTable.end() ) return decl->second.id;
     291                        if ( decl != mangleTable.end() ) return decl->second;
    297292                }
    298293
     
    309304                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    310305                                // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    311                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true;
     306                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true;
    312307                        }
    313308                }
     
    326321                                // check for C decls with the same name, skipping
    327322                                // those with an incompatible type (by mangleName)
    328                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true;
     323                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true;
    329324                        }
    330325                }
     
    408403        }
    409404
    410         void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) {
     405        void Indexer::addId( DeclarationWithType *decl ) {
    411406                debugPrint( "Adding Id " << decl->name << std::endl );
    412407                makeWritable();
     
    444439
    445440                // add to indexer
    446                 tables->idTable[ name ][ mangleName ] = { decl, baseExpr };
     441                tables->idTable[ name ][ mangleName ] = decl;
    447442                ++tables->size;
    448443        }
     
    568563                        if ( ! addedDeclConflicts( existing->second, decl ) ) {
    569564                                existing->second = decl;
    570                         }
    571                 }
    572         }
    573 
    574         void Indexer::addWith( WithStmt * stmt ) {
    575                 for ( Expression * expr : stmt->exprs ) {
    576                         if ( expr->result ) {
    577                                 AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
    578                                 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    579 
    580                                 for ( Declaration * decl : aggr->members ) {
    581                                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    582                                                 addId( dwt, expr );
    583                                         }
    584                                 }
    585565                        }
    586566                }
     
    665645
    666646        }
    667 
    668         Expression * Indexer::IdData::combine() const {
    669                 if ( baseExpr ) {
    670                         Expression * base = baseExpr->clone();
    671                         ResolvExpr::referenceToRvalueConversion( base );
    672                         Expression * ret = new MemberExpr( id, base );
    673                         // xxx - this introduces hidden environments, for now remove them.
    674                         // std::swap( base->env, ret->env );
    675                         delete base->env;
    676                         base->env = nullptr;
    677                         return ret;
    678                 } else {
    679                         return new VariableExpr( id );
    680                 }
    681         }
    682647} // namespace SymTab
    683648
  • src/SymTab/Indexer.h

    r65197c2 r12d2dc8  
    3939                void leaveScope();
    4040
    41                 struct IdData {
    42                         DeclarationWithType * id;
    43                         Expression * baseExpr; // WithExpr
    44 
    45                         Expression * combine() const;
    46                 };
    47 
    4841                /// Gets all declarations with the given ID
    49                 void lookupId( const std::string &id, std::list< IdData > &out ) const;
     42                void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const;
    5043                /// Gets the top-most type declaration with the given ID
    5144                NamedTypeDecl *lookupType( const std::string &id ) const;
     
    7467                TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
    7568
    76                 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr );
     69                void addId( DeclarationWithType *decl );
    7770                void addType( NamedTypeDecl *decl );
    7871                void addStruct( const std::string &id );
     
    8275                void addUnion( UnionDecl *decl );
    8376                void addTrait( TraitDecl *decl );
    84 
    85                 /// adds all of the IDs from WithStmt exprs
    86                 void addWith( WithStmt * );
    8777
    8878                /// convenience function for adding a list of Ids to the indexer
     
    110100                // so that they will not be selected
    111101                // void removeSpecialOverrides( FunctionDecl *decl );
    112                 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
     102                void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const;
    113103
    114104                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
  • src/SynTree/Mutator.cc

    r65197c2 r12d2dc8  
    203203}
    204204
    205 Statement * Mutator::mutate( WithStmt * withStmt ) {
    206         mutateAll( withStmt->exprs, *this );
    207         withStmt->stmt = maybeMutate( withStmt->stmt, *this );
    208         return withStmt;
    209 }
    210 
    211205NullStmt * Mutator::mutate( NullStmt *nullStmt ) {
    212206        return nullStmt;
  • src/SynTree/Mutator.h

    r65197c2 r12d2dc8  
    5050        virtual Statement * mutate( FinallyStmt * catchStmt );
    5151        virtual Statement * mutate( WaitForStmt * waitforStmt );
    52         virtual Statement * mutate( WithStmt * withStmt );
    5352        virtual NullStmt * mutate( NullStmt * nullStmt );
    5453        virtual Statement * mutate( DeclStmt * declStmt );
  • src/SynTree/ReferenceToType.cc

    r65197c2 r12d2dc8  
    7070bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; }
    7171
    72 AggregateDecl * StructInstType::getAggr() { return baseStruct; }
    73 
    7472void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    7573        assert( baseStruct );
     
    103101
    104102bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
    105 
    106 AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
    107103
    108104void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
  • src/SynTree/Statement.cc

    r65197c2 r12d2dc8  
    456456}
    457457
    458 
    459 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
    460 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
    461         cloneAll( other.exprs, exprs );
    462 }
    463 WithStmt::~WithStmt() {
    464         deleteAll( exprs );
    465         delete stmt;
    466 }
    467 
    468 void WithStmt::print( std::ostream & os, Indenter indent ) const {
    469         os << "With statement" << endl;
    470         os << indent << "... with statement:" << endl << indent+1;
    471         stmt->print( os, indent+1 );
    472 }
    473 
    474 
    475458NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) {
    476459}
  • src/SynTree/Statement.h

    r65197c2 r12d2dc8  
    431431};
    432432
    433 class WithStmt : public Statement {
    434 public:
    435         std::list< Expression * > exprs;
    436         Statement * stmt;
    437 
    438         WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
    439         WithStmt( const WithStmt & other );
    440         virtual ~WithStmt();
    441 
    442         virtual WithStmt * clone() const override { return new WithStmt( *this ); }
    443         virtual void accept( Visitor & v ) override { v.visit( this ); }
    444         virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    445         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    446 };
    447 
    448433
    449434// represents a declaration that occurs as part of a compound statement
  • src/SynTree/SynTree.h

    r65197c2 r12d2dc8  
    5555class FinallyStmt;
    5656class WaitForStmt;
    57 class WithStmt;
    5857class NullStmt;
    5958class DeclStmt;
  • src/SynTree/Type.h

    r65197c2 r12d2dc8  
    178178        virtual bool isComplete() const { return true; }
    179179
    180         virtual AggregateDecl * getAggr() {     assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); }
    181 
    182180        virtual Type *clone() const = 0;
    183181        virtual void accept( Visitor & v ) = 0;
     
    407405        virtual bool isComplete() const override;
    408406
    409         virtual AggregateDecl * getAggr() override;
    410 
    411407        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    412408        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    440436
    441437        virtual bool isComplete() const override;
    442 
    443         virtual AggregateDecl * getAggr() override;
    444438
    445439        /// looks up the members of this union named "name" and places them into "foundDecls"
  • src/SynTree/Visitor.cc

    r65197c2 r12d2dc8  
    174174}
    175175
    176 void Visitor::visit( WithStmt * withStmt ) {
    177         acceptAll( withStmt->exprs, *this );
    178         maybeAccept( withStmt->stmt, *this );
    179 }
    180 
    181 void Visitor::visit( NullStmt * ) {
     176void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) {
    182177}
    183178
  • src/SynTree/Visitor.h

    r65197c2 r12d2dc8  
    5252        virtual void visit( FinallyStmt * finallyStmt );
    5353        virtual void visit( WaitForStmt * waitforStmt );
    54         virtual void visit( WithStmt * withStmt );
    5554        virtual void visit( NullStmt * nullStmt );
    5655        virtual void visit( DeclStmt * declStmt );
  • src/tests/.expect/declarationErrors.txt

    r65197c2 r12d2dc8  
    77declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
    88  with members
    9     i: int
    109   with body
    1110
     
    1312declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
    1413  with members
    15     i: int
    1614   with body
    1715
Note: See TracChangeset for help on using the changeset viewer.